限时优惠活动
亲爱的苦力吧用户,我们为了回馈新老用户一直以来的鼎力支持,即日起(2025-02-06至2025-03-06)凡是购买苦力吧VIP/充值K币的新老用户,都直接可获得买一送一的优惠馈赠。例如:购买一个月的VIP会员可直接获得两个月的VIP会员;充值100K币可直接获得200K币,以此类推!有任何疑问可联系在线客服,感谢各位用户对苦力吧素材的信任与厚爱,我们将一如既往的给大家上新更多优质的素材源码,祝大家开工大吉、工作顺利、心想事成。

javascript实现的自定义日期选择器插件

所属分类: 网页特效-日期时间    2023-11-28 04:59:54

javascript实现的自定义日期选择器插件 ie兼容6
 查看演示  登录后下载 温馨提示
登录会员即可享受免费下载
 我要建站

javascript实现的自定义日期选择器插件(共3个文件)

    • index.html

使用方法

  • code
  • source
  1. function getWeekNumber(date) {
  2. const firstDayOfTheYear = new Date(date.getFullYear(), 0, 1);
  3. const pastDaysOfYear = (date.getTime() - firstDayOfTheYear.getTime()) / 86400000;
  4. return Math.ceil((pastDaysOfYear + firstDayOfTheYear.getDay() + 1) / 7)
  5. }
  6. function isLeapYear(year) {
  7. return year % 100 === 0 ? year % 400 === 0 : year % 4 === 0;
  8. }
  9. class Day {
  10. constructor(date = null, lang = 'default') {
  11. date = date ?? new Date();
  12. this.Date = date;
  13. this.date = date.getDate();
  14. this.day = date.toLocaleString(lang, { weekday: 'long'});
  15. this.dayNumber = date.getDay() + 1;
  16. this.dayShort = date.toLocaleString(lang, { weekday: 'short'});
  17. this.year = date.getFullYear();
  18. this.yearShort = date.toLocaleString(lang, { year: '2-digit'});
  19. this.month = date.toLocaleString(lang, { month: 'long'});
  20. this.monthShort = date.toLocaleString(lang, { month: 'short'});
  21. this.monthNumber = date.getMonth() + 1;
  22. this.timestamp = date.getTime();
  23. this.week = getWeekNumber(date);
  24. }
  25. get isToday() {
  26. return this.isEqualTo(new Date());
  27. }
  28. isEqualTo(date) {
  29. date = date instanceof Day ? date.Date : date;
  30. return date.getDate() === this.date &&
  31. date.getMonth() === this.monthNumber - 1 &&
  32. date.getFullYear() === this.year;
  33. }
  34. format(formatStr) {
  35. return formatStr
  36. .replace(/\\bYYYY\\b/, this.year)
  37. .replace(/\\bYYY\\b/, this.yearShort)
  38. .replace(/\\bWW\\b/, this.week.toString().padStart(2, '0'))
  39. .replace(/\\bW\\b/, this.week)
  40. .replace(/\\bDDDD\\b/, this.day)
  41. .replace(/\\bDDD\\b/, this.dayShort)
  42. .replace(/\\bDD\\b/, this.date.toString().padStart(2, '0'))
  43. .replace(/\\bD\\b/, this.date)
  44. .replace(/\\bMMMM\\b/, this.month)
  45. .replace(/\\bMMM\\b/, this.monthShort)
  46. .replace(/\\bMM\\b/, this.monthNumber.toString().padStart(2, '0'))
  47. .replace(/\\bM\\b/, this.monthNumber)
  48. }
  49. }
  50. class Month {
  51. constructor(date = null, lang = 'default') {
  52. const day = new Day(date, lang);
  53. const monthsSize = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  54. this.lang = lang;
  55. this.name = day.month;
  56. this.number = day.monthNumber;
  57. this.year = day.year;
  58. this.numberOfDays = monthsSize[this.number - 1];
  59. if(this.number === 2) {
  60. this.numberOfDays += isLeapYear(day.year) ? 1 : 0;
  61. }
  62. this[Symbol.iterator] = function* () {
  63. let number = 1;
  64. yield this.getDay(number);
  65. while(number < this.numberOfDays) {
  66. ++number;
  67. yield this.getDay(number);
  68. }
  69. }
  70. }
  71. getDay(date) {
  72. return new Day(new Date(this.year, this.number - 1, date), this.lang);
  73. }
  74. }
  75. class Calendar {
  76. weekDays = Array.from({length: 7});
  77. constructor(year = null, monthNumber = null, lang = 'default') {
  78. this.today = new Day(null, lang);
  79. this.year = year ?? this.today.year;
  80. this.month = new Month(new Date(this.year, (monthNumber || this.today.monthNumber) - 1), lang);
  81. this.lang = lang;
  82. this[Symbol.iterator] = function* () {
  83. let number = 1;
  84. yield this.getMonth(number);
  85. while(number < 12) {
  86. ++number;
  87. yield this.getMonth(number);
  88. }
  89. }
  90. this.weekDays.forEach((_, i) => {
  91. const day = this.month.getDay(i + 1);
  92. if(!this.weekDays.includes(day.day)) {
  93. this.weekDays[day.dayNumber - 1] = day.day
  94. }
  95. })
  96. }
  97. get isLeapYear() {
  98. return isLeapYear(this.year);
  99. }
  100. getMonth(monthNumber) {
  101. return new Month(new Date(this.year, monthNumber - 1), this.lang);
  102. }
  103. getPreviousMonth() {
  104. if(this.month.number === 1) {
  105. return new Month(new Date(this.year - 1, 11), this.lang);
  106. }
  107. return new Month(new Date(this.year, this.month.number - 2), this.lang);
  108. }
  109. getNextMonth() {
  110. if(this.month.number === 12) {
  111. return new Month(new Date(this.year + 1, 0), this.lang);
  112. }
  113. return new Month(new Date(this.year, this.month.number + 2), this.lang);
  114. }
  115. goToDate(monthNumber, year) {
  116. this.month = new Month(new Date(year, monthNumber - 1), this.lang);
  117. this.year = year;
  118. }
  119. goToNextYear() {
  120. this.year += 1;
  121. this.month = new Month(new Date(this.year, 0), this.lang);
  122. }
  123. goToPreviousYear() {
  124. this.year -= 1;
  125. this.month = new Month(new Date(this.year, 11), this.lang);
  126. }
  127. goToNextMonth() {
  128. if(this.month.number === 12) {
  129. return this.goToNextYear();
  130. }
  131. this.month = new Month(new Date(this.year, (this.month.number + 1) - 1), this.lang);
  132. }
  133. goToPreviousMonth() {
  134. if(this.month.number === 1) {
  135. return this.goToPreviousYear();
  136. }
  137. this.month = new Month(new Date(this.year, (this.month.number - 1) - 1), this.lang);
  138. }
  139. }
  140. class DatePicker extends HTMLElement {
  141. format = 'MMM DD, YYYY';
  142. position = 'bottom';
  143. visible = false;
  144. date = null;
  145. mounted = false;
  146. // elements
  147. toggleButton = null;
  148. calendarDropDown = null;
  149. calendarDateElement = null;
  150. calendarDaysContainer = null;
  151. selectedDayElement = null;
  152. constructor() {
  153. super();
  154. const lang = window.navigator.language;
  155. const date = new Date(this.date ?? (this.getAttribute("date") || Date.now()));
  156. this.shadow = this.attachShadow({mode: "open"});
  157. this.date = new Day(date, lang);
  158. this.calendar = new Calendar(this.date.year, this.date.monthNumber, lang);
  159. this.format = this.getAttribute('format') || this.format;
  160. this.position = DatePicker.position.includes(this.getAttribute('position'))
  161. ? this.getAttribute('position')
  162. : this.position;
  163. this.visible = this.getAttribute('visible') === ''
  164. || this.getAttribute('visible') === 'true'
  165. || this.visible;
  166. this.render();
  167. }
  168. connectedCallback() {
  169. this.mounted = true;
  170. this.toggleButton = this.shadow.querySelector('.date-toggle');
  171. this.calendarDropDown = this.shadow.querySelector('.calendar-dropdown');
  172. const [prevBtn, calendarDateElement, nextButton] = this.calendarDropDown
  173. .querySelector('.header').children;
  174. this.calendarDateElement = calendarDateElement;
  175. this.calendarDaysContainer = this.calendarDropDown.querySelector('.month-days');
  176. this.toggleButton.addEventListener('click', () => this.toggleCalendar());
  177. prevBtn.addEventListener('click', () => this.prevMonth());
  178. nextButton.addEventListener('click', () => this.nextMonth());
  179. document.addEventListener('click', (e) => this.handleClickOut(e));
  180. this.renderCalendarDays();
  181. }
  182. attributeChangedCallback(name, oldValue, newValue) {
  183. if(!this.mounted) return;
  184. switch(name) {
  185. case "date":
  186. this.date = new Day(new Date(newValue));
  187. this.calendar.goToDate(this.date.monthNumber, this.date.year);
  188. this.renderCalendarDays();
  189. this.updateToggleText();
  190. break;
  191. case "format":
  192. this.format = newValue;
  193. this.updateToggleText();
  194. break;
  195. case "visible":
  196. this.visible = ['', 'true', 'false'].includes(newValue)
  197. ? newValue === '' || newValue === 'true'
  198. : this.visible;
  199. this.toggleCalendar(this.visible);
  200. break;
  201. case "position":
  202. this.position = DatePicker.position.includes(newValue)
  203. ? newValue
  204. : this.position;
  205. this.calendarDropDown.className =
  206. `calendar-dropdown ${this.visible ? 'visible' : ''} ${this.position}`;
  207. break;
  208. }
  209. }
  210. toggleCalendar(visible = null) {
  211. if(visible === null) {
  212. this.calendarDropDown.classList.toggle('visible');
  213. } else if(visible) {
  214. this.calendarDropDown.classList.add('visible');
  215. } else {
  216. this.calendarDropDown.classList.remove('visible');
  217. }
  218. this.visible = this.calendarDropDown.className.includes('visible');
  219. if(this.visible) {
  220. this.calendarDateElement.focus();
  221. } else {
  222. this.toggleButton.focus();
  223. if(!this.isCurrentCalendarMonth()) {
  224. this.calendar.goToDate(this.date.monthNumber, this.date.year);
  225. this.renderCalendarDays();
  226. }
  227. }
  228. }
  229. prevMonth() {
  230. this.calendar.goToPreviousMonth();
  231. this.renderCalendarDays();
  232. }
  233. nextMonth() {
  234. this.calendar.goToNextMonth();
  235. this.renderCalendarDays();
  236. }
  237. updateHeaderText() {
  238. this.calendarDateElement.textContent =
  239. `${this.calendar.month.name}, ${this.calendar.year}`;
  240. const monthYear = `${this.calendar.month.name}, ${this.calendar.year}`
  241. this.calendarDateElement
  242. .setAttribute('aria-label', `current month ${monthYear}`);
  243. }
  244. isSelectedDate(date) {
  245. return date.date === this.date.date &&
  246. date.monthNumber === this.date.monthNumber &&
  247. date.year === this.date.year;
  248. }
  249. isCurrentCalendarMonth() {
  250. return this.calendar.month.number === this.date.monthNumber &&
  251. this.calendar.year === this.date.year;
  252. }
  253. selectDay(el, day) {
  254. if(day.isEqualTo(this.date)) return;
  255. this.date = day;
  256. if(day.monthNumber !== this.calendar.month.number) {
  257. this.prevMonth();
  258. } else {
  259. el.classList.add('selected');
  260. this.selectedDayElement.classList.remove('selected');
  261. this.selectedDayElement = el;
  262. }
  263. this.toggleCalendar();
  264. this.updateToggleText();
  265. }
  266. handleClickOut(e) {
  267. if(this.visible && (this !== e.target)) {
  268. this.toggleCalendar(false);
  269. }
  270. }
  271. getWeekDaysElementStrings() {
  272. return this.calendar.weekDays
  273. .map(weekDay => `<span>${weekDay.substring(0, 3)}</span>`)
  274. .join('');
  275. }
  276. getMonthDaysGrid() {
  277. const firstDayOfTheMonth = this.calendar.month.getDay(1);
  278. const prevMonth = this.calendar.getPreviousMonth();
  279. const totalLastMonthFinalDays = firstDayOfTheMonth.dayNumber - 1;
  280. const totalDays = this.calendar.month.numberOfDays + totalLastMonthFinalDa<p></p>
function getWeekNumber(date) {
  const firstDayOfTheYear = new Date(date.getFullYear(), 0, 1);
    const pastDaysOfYear = (date.getTime() - firstDayOfTheYear.getTime()) / 86400000;
    
    return Math.ceil((pastDaysOfYear + firstDayOfTheYear.getDay() + 1) / 7)
}

function isLeapYear(year) {
  return year % 100 === 0 ? year % 400 === 0 : year % 4 === 0;
}

class Day {
  constructor(date = null, lang = 'default') {
    date = date ?? new Date();
    
    this.Date = date;
    this.date = date.getDate();
    this.day = date.toLocaleString(lang, { weekday: 'long'});
    this.dayNumber = date.getDay() + 1;
    this.dayShort = date.toLocaleString(lang, { weekday: 'short'});
    this.year = date.getFullYear();
    this.yearShort = date.toLocaleString(lang, { year: '2-digit'});
    this.month = date.toLocaleString(lang, { month: 'long'});
    this.monthShort = date.toLocaleString(lang, { month: 'short'});
    this.monthNumber = date.getMonth() + 1;
    this.timestamp = date.getTime();
    this.week = getWeekNumber(date);
  }
  
  get isToday() {
    return this.isEqualTo(new Date());
  }
  
  isEqualTo(date) {
    date = date instanceof Day ? date.Date : date;
    
    return date.getDate() === this.date &&
      date.getMonth() === this.monthNumber - 1 &&
      date.getFullYear() === this.year;
  }
  
  format(formatStr) {
    return formatStr
      .replace(/\\bYYYY\\b/, this.year)
      .replace(/\\bYYY\\b/, this.yearShort)
      .replace(/\\bWW\\b/, this.week.toString().padStart(2, '0'))
      .replace(/\\bW\\b/, this.week)
      .replace(/\\bDDDD\\b/, this.day)
      .replace(/\\bDDD\\b/, this.dayShort)
      .replace(/\\bDD\\b/, this.date.toString().padStart(2, '0'))
      .replace(/\\bD\\b/, this.date)
      .replace(/\\bMMMM\\b/, this.month)
      .replace(/\\bMMM\\b/, this.monthShort)
      .replace(/\\bMM\\b/, this.monthNumber.toString().padStart(2, '0'))
      .replace(/\\bM\\b/, this.monthNumber)
  }
}

class Month {
  constructor(date = null, lang = 'default') {
    const day = new Day(date, lang);
    const monthsSize = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    this.lang = lang;
    
    this.name = day.month;
    this.number = day.monthNumber;
    this.year = day.year;
    this.numberOfDays = monthsSize[this.number - 1];
    
    if(this.number === 2) {
      this.numberOfDays += isLeapYear(day.year) ? 1 : 0;
    }
    
    this[Symbol.iterator] = function* () {
      let number = 1;
      yield this.getDay(number);
      while(number < this.numberOfDays) {
        ++number;
        yield this.getDay(number);
      }
    }
  }
  
  getDay(date) {
    return new Day(new Date(this.year, this.number - 1, date), this.lang);
  }
}

class Calendar {
  weekDays = Array.from({length: 7});
  
  constructor(year = null, monthNumber = null, lang = 'default') {
    this.today = new Day(null, lang);
    this.year = year ?? this.today.year;
    this.month = new Month(new Date(this.year, (monthNumber || this.today.monthNumber) - 1), lang);
    this.lang = lang;
    
    this[Symbol.iterator] = function* () {
      let number = 1;
      yield this.getMonth(number);
      while(number < 12) {
        ++number;
        yield this.getMonth(number);
      }
    }
    
    this.weekDays.forEach((_, i) => {
      const day = this.month.getDay(i + 1);
      if(!this.weekDays.includes(day.day)) {
        this.weekDays[day.dayNumber - 1] = day.day
      }
    })
  }
  
  get isLeapYear() {
    return isLeapYear(this.year);
  }
  
  getMonth(monthNumber) {
    return new Month(new Date(this.year, monthNumber - 1), this.lang);
  }
  
  getPreviousMonth() {
    if(this.month.number === 1) {
      return new Month(new Date(this.year - 1, 11), this.lang);
    }
    
    return new Month(new Date(this.year, this.month.number - 2), this.lang);
  }
  
  getNextMonth() {
    if(this.month.number === 12) {
      return new Month(new Date(this.year + 1, 0), this.lang);
    }
    
    return new Month(new Date(this.year, this.month.number + 2), this.lang);
  }
  
  goToDate(monthNumber, year) {
    this.month = new Month(new Date(year, monthNumber - 1), this.lang);
    this.year = year;
  }
  
  goToNextYear() {
    this.year += 1;
    this.month = new Month(new Date(this.year, 0), this.lang);
  }
  
  goToPreviousYear() {
    this.year -= 1;
    this.month = new Month(new Date(this.year, 11), this.lang);
  }
  
  goToNextMonth() {
    if(this.month.number === 12) {
      return this.goToNextYear();
    }
    
    this.month = new Month(new Date(this.year, (this.month.number + 1) - 1), this.lang);
  }
  
  goToPreviousMonth() {
    if(this.month.number === 1) {
      return this.goToPreviousYear();
    }
    
    this.month = new Month(new Date(this.year, (this.month.number - 1) - 1), this.lang);
  }
}

class DatePicker extends HTMLElement {
  format = 'MMM DD, YYYY';
  position = 'bottom';
  visible = false;
  date = null;
  mounted = false;
  // elements
  toggleButton = null;
  calendarDropDown = null;
  calendarDateElement = null;
  calendarDaysContainer = null;
  selectedDayElement = null;
  
  constructor() {
    super();
    
    const lang = window.navigator.language;
    const date = new Date(this.date ?? (this.getAttribute("date") || Date.now()));
    
    this.shadow = this.attachShadow({mode: "open"});
    this.date = new Day(date, lang);
    this.calendar = new Calendar(this.date.year, this.date.monthNumber, lang);
    
    this.format = this.getAttribute('format') || this.format;
    this.position = DatePicker.position.includes(this.getAttribute('position'))
      ? this.getAttribute('position')
      : this.position;
    this.visible = this.getAttribute('visible') === '' 
      || this.getAttribute('visible') === 'true'
      || this.visible;
    
    this.render();
  }
  
  connectedCallback() {
    this.mounted = true;
    
    this.toggleButton = this.shadow.querySelector('.date-toggle');
    this.calendarDropDown = this.shadow.querySelector('.calendar-dropdown');
    const [prevBtn, calendarDateElement, nextButton] = this.calendarDropDown
      .querySelector('.header').children;
    this.calendarDateElement = calendarDateElement;
    this.calendarDaysContainer = this.calendarDropDown.querySelector('.month-days');
    
    this.toggleButton.addEventListener('click', () => this.toggleCalendar());
    prevBtn.addEventListener('click', () => this.prevMonth());
    nextButton.addEventListener('click', () => this.nextMonth());
    document.addEventListener('click', (e) => this.handleClickOut(e));
    
    this.renderCalendarDays();
  }
  
  attributeChangedCallback(name, oldValue, newValue) {
    if(!this.mounted) return;
    
    switch(name) {
      case "date":
        this.date = new Day(new Date(newValue));
        this.calendar.goToDate(this.date.monthNumber, this.date.year);
        this.renderCalendarDays();
        this.updateToggleText();
        break;
      case "format":
        this.format = newValue;
        this.updateToggleText();
        break;
      case "visible":
        this.visible = ['', 'true', 'false'].includes(newValue) 
          ? newValue === '' || newValue === 'true'
          : this.visible;
        this.toggleCalendar(this.visible);
        break;
      case "position":
        this.position = DatePicker.position.includes(newValue)
          ? newValue
          : this.position;
        this.calendarDropDown.className = 
          `calendar-dropdown ${this.visible ? 'visible' : ''} ${this.position}`;
        break;
    }
  }
  
  toggleCalendar(visible = null) {
    if(visible === null) {
      this.calendarDropDown.classList.toggle('visible');
    } else if(visible) {
      this.calendarDropDown.classList.add('visible');
    } else {
      this.calendarDropDown.classList.remove('visible');
    }
    
    this.visible = this.calendarDropDown.className.includes('visible');
    
    if(this.visible) {
      this.calendarDateElement.focus();
    } else {
      this.toggleButton.focus();
      
      if(!this.isCurrentCalendarMonth()) {
        this.calendar.goToDate(this.date.monthNumber, this.date.year);
        this.renderCalendarDays();
      }
    }
  }
  
  prevMonth() {
    this.calendar.goToPreviousMonth();
    this.renderCalendarDays();
  }
  
  nextMonth() {
    this.calendar.goToNextMonth();
    this.renderCalendarDays();
  }
  
  updateHeaderText() {
    this.calendarDateElement.textContent = 
      `${this.calendar.month.name}, ${this.calendar.year}`;
    const monthYear = `${this.calendar.month.name}, ${this.calendar.year}`
    this.calendarDateElement
      .setAttribute('aria-label', `current month ${monthYear}`);
  }
  
  isSelectedDate(date) {
    return date.date === this.date.date &&
      date.monthNumber === this.date.monthNumber &&
      date.year === this.date.year;
  }
  
  isCurrentCalendarMonth() {
    return this.calendar.month.number === this.date.monthNumber &&
      this.calendar.year === this.date.year;
  }
  
  selectDay(el, day) {
    if(day.isEqualTo(this.date)) return;
    
    this.date = day;
    
    if(day.monthNumber !== this.calendar.month.number) {
      this.prevMonth();
    } else {
      el.classList.add('selected');
      this.selectedDayElement.classList.remove('selected');
      this.selectedDayElement = el;
    }
    
    this.toggleCalendar();
    this.updateToggleText();
  }
  
  handleClickOut(e) {
    if(this.visible && (this !== e.target)) {
      this.toggleCalendar(false);
    }
  }
  
  getWeekDaysElementStrings() {
    return this.calendar.weekDays
      .map(weekDay => `<span>${weekDay.substring(0, 3)}</span>`)
      .join('');
  }
  
  getMonthDaysGrid() {
    const firstDayOfTheMonth = this.calendar.month.getDay(1);
    const prevMonth = this.calendar.getPreviousMonth();
    const totalLastMonthFinalDays = firstDayOfTheMonth.dayNumber - 1;
    const totalDays = this.calendar.month.numberOfDays + totalLastMonthFinalDa<p></p>
                                                
站长提示:
1. 苦力吧素材官方QQ群:950875342
2. 平台上所有素材资源,需注册登录会员方能正常下载。
3. 会员用户积极反馈网站、素材资源BUG或错误问题,每次奖励2K币
4. PHP源码类素材,如需协助安装调试,或你有二次开发需求,可联系苦力吧客服。
5. 付费素材资源,需充值后方能下载,如有任何疑问可直接联系苦力吧客服
相关资源 / 日期时间

2024新年倒计时雪花飘落特效代码

一款新年倒计时特效代码,随机位置大小的雪花从天而降,效果很逼真!倒计时可指定一个日期时间,自动倒计时(天时分秒)。
  日期时间
 4523  0

jquery响应式日历方块热图插件

CalendarHeatmap.js是一个日历热图插件,可生成一个动态交互式、可自定义的日历热图,用于表示时间序列数据。鼠标悬停在小方格上,可显示当前日期时间。
  日期时间
 3315  0

jquery模拟在线动画手表特效代码

一款逼真的模拟手表时间显示效果,手表表盘中时分秒精准显示,非常有意思!
  日期时间
 5187  0

jquery显示当前本地时间模拟时钟插件

jquery显示当前本地时间模拟时钟特效!
  日期时间
 3331  0

评论数(2) 回复有机会获得K币 用户协议

    kuliwa0
    2023-12-15 19:54:32
    NoMeaning0
    2023-12-06 17:45:12
    苦力吧还是靠谱,中文的日历插件~
    回复 2
😀
  • 😀
  • 😊
  • 😂
  • 😍
  • 😑
  • 😷
  • 😵
  • 😛
  • 😣
  • 😱
  • 😋
  • 😎
  • 😵
  • 😕
  • 😶
  • 😚
  • 😜
  • 😭
发表评论