Как сделать календарь на js
Перейти к содержимому

Как сделать календарь на js

  • автор:

Как сделать календарь на js

Напишите функцию createCalendar(elem, year, month) .

Вызов функции должен создать календарь для заданного месяца month в году year и вставить его в elem .

Например, createCalendar(cal, 2012, 9) сгенерирует в cal следующий календарь:

P.S. В этой задаче достаточно сгенерировать календарь, кликабельным его делать не нужно.

Для решения задачи сгенерируем таблицу в виде строки: «

.

» , а затем присвоим в innerHTML .

Как на JS можно создать календарь?

31b972eb9c6a41c0a08b7a4a22ae9e98.png

Как создать вот такой календарь на JS?

  • Вопрос задан более трёх лет назад
  • 3295 просмотров

Комментировать

Решения вопроса 0

Ответы на вопрос 3

bootd

Гугли и ты откроешь врата знаний!

Своё вы не напишите. Раз спрашиваете о таком вопросе.
Сверстать такую штуку, не сложно. Делов то, обычную сетку из блоков сделать в изи. Таблица подходит идеально для этого. Но привязать ко всему этому js вы не сможете(мне так кажется). У вас вылезет ну просто тьма вопросов, которыми вы заспамите тостер(например: переключение месяцев, вешание событий на нужную дату и прочее, работа с датами — очень геморойно для новичка). Для самообущения делайте, но разбирая чужие библиотеки. Если вам нужно решение уже для готового сайта, то воспользуйтесь готовой библиотекой. Гугл -> js calendar

Ответ написан более трёх лет назад

Нравится 5 9 комментариев

Календарь для сайта | JavaScript

Можно сделать большие подсказки (как сделать). Но это базовый образец и усложнять его не хочется.

Полный календарь, где даты идут вслед

В коде выше в JS строку

if (DNfirst != 0) < for(var i = 1; i < DNfirst; i++) calendar += ''; >else< for(var i = 0; i < 6; i++) calendar += ''; >

заменить на

if (DNfirst != 0) < for(var i = 1; i < DNfirst; i++) calendar += ''+[new Date(new Date(year,[m-1],1).getFullYear(),new Date(year,[m-1],1).getMonth()+1,0).getDate() - DNfirst + i + 1]; >else< for(var i = 0; i < 6; i++) calendar += ''+[new Date(new Date(year,[m-1],1).getFullYear(),new Date(year,[m-1],1).getMonth()+1,0).getDate() + i - 5]; >
if (DNlast != 0) < for(var i = DNlast; i < 7; i++) calendar += ''; >

заменить на

if (DNlast != 0) < for(var i = DNlast; i < 7; i++) calendar += '' + [i +1-DNlast]; >

Добавить CSS перед закрывающимся тегом

:

#calendarBig table tbody td.next < /* выделенные даты-ссылки под курсором */ color: #ccc; >

68 комментариев:

Анонимный Полезная информация, благодарствую 🙂 NMitra Совсем не запланированная: накопились знания про new Date() при написании цикла «сколько часов, сколько минут. «, которые тут и использовала. Анонимный Отлично всё работает. Очень полезно для верстальщика. NMitra Да, я понимаю, что это не конечный вариант, и понимаю, что проще написать своё «творение», чем разбираться в чужой работе. Поэтому стараюсь либо давать самое простое решение, либо писать комментарии. Aleksey NMitra, спасибо. Своё «творение» писать не проще, но приходится. И без таких «самых простых решений» это сделать очень трудно (долго). У меня календарь занял около 600 строк js, К сожалению выложить его не могу, но могу показать http://result-systems.ru/dbopen?RF.TVR/DP_2013
Там список документов — откройте любой в режиме правки. Календарь рассчитан на ввод с клавиатуры. Открыть по Enter NMitra Заценила 🙂 Анонимный отличные календари) но как заставить работать календарь со стрелками в IE (желательно IE8)? а то сами стрелки не работают( NMitra Десятка норм. Честно говоря, не могу сказать что там именно ему не нравится. Возможно document.querySelector (не помню когда начал поддерживать) или он с селекторами CSS не дружит. ( Анонимный Ошибка в коде 2-го календаря (со стрелками-переключателями). Если сегодня 31-е число вы не сможете переключиться на месяца в которых нет 31-го числа, либо не сможете переключиться на невисокосный февраль, если сегодня число большее, чем 28-е. Да вообще много ошибок, хотя и не критичных, в коде, например не генерируются закрывающие теги для ячеек и строчек таблицы, многократно используются вызовы функций для получения одних и тех же значений, вместо сохранения в переменную и последующего использования, постоянно используются длинные цепочки в querySelector вместо назначения id на нужный элемент и выборки его по id. Но вообщем код рабочий, за исключением описанного бага, за что огромная благодарность автору. NMitra Спасибо за бдительность. Код подправила. Теперь как по маслу.

Закрывающиеся теги не нужны http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#syntax-tag-omission
Точно, querySelector я люблю без меры. Разница с id незначительна.
Вызовы функций, предполагаю, каждый под себя сделает. Зато так понятно что откуда берётся. Учитывая, что я сегодня на код смотрела как в первый раз, сразу в нём разобралась. Анонимный Экспериментировать можно и нужно в процессе саморазвития, но в коммерческих (да и любых других проектах) лучше использовать готовые проверенные и отлаженные решения (их масса беЗплатных). Как пример http://jqueryui.com/datepicker/ или http://plugins.jquery.com/tag/calendar/ (их довольно много, не только джекверных, они кроссбраузерны и кастомизируемы и т.д.). Цените своё время и экономьте средства заказчика. NMitra Согласна. Для себя считаю так. Код пишется для новых версий браузера. В приоритете мобильные телефоны, планшеты, ноутбуки. Они быстро морально устаревают или ломаются. Как ни крути их пользователи установят последние версии браузеров.

Прозрачность, выделение столбцов таблицы, и т.п. Для пользователей новых версий браузеров будет всё красиво и юзабильно. Для старых версий должно быть доступно. То есть чтобы они могли воспользоваться функциями, заказать товар, вёрстка не съезжала, но при заполнении поля input не будет показан календарь. Они просто ручками наберут нужную дату. Анонимный Всем привет. Мне надо сделать так, чтобы при нажатии на день календаря джаваскриптом стягивало число, месяц и год, и заносило это дело в поле (скрытое, но для теста сделал поля видимыми). Когда нахожусь на текущем месяце, то все отлично: http://prntscr.com/40xg4r
А вот стоит мне переключить месяц, все остается также http://prntscr.com/40xgrj . Ошибок инспектор кода не выдает. NMitra Нашлась минутка для ответа. Предполагаю идея должна быть ясна: day2() нужно добавлять и при переключении месяцев:

function day2() var day2 = document.querySelectorAll(‘#calendar2 tbody td’);
for (var i = 0; i < day2.length; i++) day2[i].onclick = function() document.querySelector('#rez').innerHTML = this.innerHTML + ' ' + parseFloat(parseFloat(this.parentNode.parentNode.parentNode.querySelector('thead td:nth-child(2)').dataset.month) + 1) + ' ' + this.parentNode.parentNode.parentNode.querySelector('thead td:nth-child(2)').dataset.year;
>
>
>

Calendar2(«calendar2», new Date().getFullYear(), new Date().getMonth());

// переключатель минус месяц
document.querySelector(‘#calendar2 thead tr:nth-child(1) td:nth-child(1)’).onclick = function() Calendar2(«calendar2», document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.year, parseFloat(document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.month)-1);
day2();
>

// переключатель плюс месяц
document.querySelector(‘#calendar2 thead tr:nth-child(1) td:nth-child(3)’).onclick = function() Calendar2(«calendar2», document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.year, parseFloat(document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.month)+1);
day2();
>
Анонимный Спасибо автору за статью. Буду признателен если подскажете как в календаре со стрелками (пример 2) вывести даты с ссылками и подсказками. NMitra В CSS добавьте:

#calendar2 tbody td[title] outline: 3px solid green;
background: yellow;
cursor: help;
>
#calendar2 tbody td[title] a display: block;
>

В HTML добавьте:

>
Calendar2(«calendar2», new Date().getFullYear(), new Date().getMonth());
// переключатель минус месяц
document.querySelector(‘#calendar2 thead tr:nth-child(1) td:nth-child(1)’).onclick = function() Calendar2(«calendar2», document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.year, parseFloat(document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.month)-1);
>
// переключатель плюс месяц
document.querySelector(‘#calendar2 thead tr:nth-child(1) td:nth-child(3)’).onclick = function() Calendar2(«calendar2», document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.year, parseFloat(document.querySelector(‘#calendar2 thead td:nth-child(2)’).dataset.month)+1);
> Анонимный Спасибо за оперативный ответ, очень помогли. Анонимный А как в календаре на год сделать чтобы одни даты были одного цвета, а другие другого Анонимный Имеется ввиду определенные даты заданные через data-dd, . на которых появляется подсказка NMitra Добавьте по аналогии с data-text ещё и data-class
В div (всегда прописываете)
data-class=»mytd1″
В скрипте в двух местах после myD[i].title = my.dataset.text; добавьте
myD[i].className = my.dataset.class;
Стиль будет
#calendarBig .mytd1
#calendarBig .mytd2 NMitra Пример http://jsfiddle.net/NMitra/3Ljdb2s7/ Анонимный Спасибо огромное!
Всё оказывается просто. Учиться, учиться и еще раз учиться 🙂 Андрей Бакрин Как сделать так, чтобы при клике по дате, вылезало окно с выбором цвета (2-3 цвета), пользователь мог выбрать каким цветом закрасить дату. Нужно для графика работы. NMitra Андрей, со всем уважением, но это уже делается за плату. Анонимный 1 января 2014 вообще то среда,а не вторник (браузер FF) NMitra У меня среда. А где вы смотрите (какой из калькуляторов)? Анонимный Спасибо NMitra, отличные календари, прям то что надо. NMitra Рада помочь! Виталий Привет! Очень понравился Большой календарь со всеми 12 месяцами на HTML.
Но хотелось бы переделать его: Дни недели с ПН по ВС были бы по левую и правую сторону, а даты месяцев соответственно шли бы не по горизонтали, а по вертикали.
Подскажите! NMitra Привет, с трудом представляю как это должно выглядеть. Добавьте в стили

#calendarBig transform: rotate(-90deg);
>
#calendarBig table tbody td transform: rotate(90deg);
> Виталий получается лабуда. Виталий как сделать календарь аналогично как в Виндовс 7, когда изменяешь дату с переходами в месяца, года и десятилетия? NMitra Я могу сделать чтоб ровненько было, но всё равно лабуда получится. Если у вас есть пример, когда дни недели находятся сбоку, приведите его, пожалуйста.

Календарь как в Виндовс 7 делать более трудоёмко и не бесплатно. Виталий как ещё сделать в Большом календаре на год чтобы при нажатии на день
текст выводился внизу календаря, а не во всплывающей подсказке.
NMitra Без ссылок, клик будет выводить текст под календарём http://jsfiddle.net/NMitra/uq41yoxx/
Так как календарь занимает почти всю высоту экрана монитора (особенно на планшетах), то всплывающие подсказки оставила Виталий Подскажите, как правильно добавить условие, что
today, . иначе holiday или «ещё какие-то дни», тогда . td.
т.е. параллельно с holiday
а то запутался. сори.
NMitra Когда текущий день совпадает с праздником, то что-то должно происходить?

замените на
if (
((i > 0 && i < 9) && D.getMonth() == 0) ||
(i == 23 && D.getMonth() == 1 ) ||
(i == 8 && D.getMonth() == 2) ||
(i == 1 && D.getMonth() == 4) ||
(i == 9 && D.getMonth() == 4) ||
(i == 12 && D.getMonth() == 5) ||
(i == 4 && D.getMonth() == 10)
) <
calendar += ‘ >else calendar += ‘ > NMitra И для todayPR укажите свои стили Виталий хм, так закрасились все выходные.
Нужно стилями отметить и другие дни, кроме праздников.
Т.е. есть праздники, а есть и другие памятные дни, которые нужно тоже отметить стилями отдельно от праздников и рядовых дней.
Пока не получается. NMitra if (
((i > 0 && i < 9) && D.getMonth() == 0) ||
(i == 23 && D.getMonth() == 1 ) ||
(i == 8 && D.getMonth() == 2) ||
(i == 1 && D.getMonth() == 4) ||
(i == 9 && D.getMonth() == 4) ||
(i == 12 && D.getMonth() == 5) ||
(i == 4 && D.getMonth() == 10)
) calendar += ‘>elseif (
(i == 20 && D.getMonth() == 3) ||
(i == 5 && D.getMonth() == 8 )
) calendar += ‘>elsecalendar += ‘>
>

Установите свои стили

#calendarBig .holiday, #calendarBig .todayPR color: blue;
>
#calendarBig .todayMYPR color: green;
> Виталий Вроде логику вижу, однако непонятно, где здесь должны быть эти строки:
от for(var i = 1; i и до if (DNlast != 0) NMitra Это всё остаётся, вам нужно заменить одну строку, озвученную в комментарии 38

calendar += ‘не понятно то, что это не работает. NMitra Стили нужно более подробно расписывать

#calendarBig table tbody td.holiday, #calendarBig table tbody td.todayPR color: blue;
>
#calendarBig table tbody td.todayMYPR color: green;
>

См. http://jsfiddle.net/NMitra/srdq5oc7/ Sergey Zavrazhnov Можно чтобы дата была ссылкой на другую страницу, тогда нужно написать data-link (адрес страницы, куда перенаправить пользователя). Одна дата не может вести на несколько страниц [вернее может, но в код нужно внести дополнительные изменения]

Возникла необходимость сделать дату ссылкой на несколько различных страниц. Что нужно в код добавить.
Заранее спасибо NMitra См. http://jsfiddle.net/NMitra/y2qxys9w/ Дмитрий Вашкевич Подскажите, как закрыть для выбора определенные даты в календаре (чтобы они были выделены другим цветом и их нельзя было выбрать для передачи в форму) NMitra Можно в JS, а можно только CSS и HTML.
CSS и HTML (пример http://jsfiddle.net/NMitra/t3uv1jcu/ ):

последним в calendarTable добавьте свои даты, только оставьте пустым data-text=»»

тогда в CSS внесите приблизительно такой стиль

#calendarBig table tbody td[title=»»] outline: 3px none green;
background: #ccc;
cursor: not-allowed;
> Дмитрий Шумов хороший календарь советую всем без рекламы и всего прочего NMitra Благодарю за комментарий, Дмитрий СГ приветствую! прошу вашего совета. Есть страничка на простом html, на ней церковный календарь в виде длинного списка. Как привязать какой-либо из ваших скриптов так, чтобы при открытии странички мы видели перед собою не верх страницы, а сегодняшний день? посмотреть можно здесь maristarover.ru в левом меню Месяцеслов. С уважением Сергей Генн. NMitra Привет, не поняла. Нужно чтобы страница перематывалась? Или в правой колонке висела картинка конкретного месяца? Второе делается по той же схеме http://shpargalkablog.ru/2010/07/kartinku-v-zagolovok-bloga.html#mes NMitra Первое http://shpargalkablog.ru/2015/07/hash-scrolling.html Анонимный Всем салют!Подскажите,как в календаре(на 12 мес который) сделать не три месяца в столбце,а пять,хотя бы NMitra Здравствуйте, на 5 плохо — получится что два месяца будут отшельниками. Вот по 4-ре месяца (тег tr чтоит через каждые четыре td; верхняя колонка объединяет две ячейки с помощью colspan=»2″)

i, D.getMonth() и D.getFullYear() объединены символами &&
это условие берём в скобки и при необходимости пишем ещё одно условие, также в скобках. Условия объединяются символами ||

#calendar2 tbody td.today

#calendar2 .vacation color: #919191;
> yes_59 Ok yes_59 Доброго времени суток! Спасибо! Просто замечательно! Всё работает, но вот если, например неделю каникул цветом выделить, при этом не изменяя фон текущей даты или запрограммировать, например на 15 января олимпиаду (событие) и при загрузке страницы выдавать сообщение о напоминании или подтверждении этого события. С благодарностью Александр NMitra Доброе время суток: это 2015,12-1,31 сравниваемая дата 31.12.2015. Когда текущая дата будет равна сравниваемой, появится сообщение

NMitra В стилях что ниже, то и имеет приоритет. Так текущая дата

#calendar2 .vacation <>
#calendar2 tbody td.today <>

А так дата каникул

#calendar2 tbody td.today <>
#calendar2 .vacation <>

Я бы текущую дату выделила не фоном, а рамкой

#calendar2 tbody td.today outline: 3px solid red;
>

Как сделать календарь на js

Этот виджет календаря не требует внешних библиотек, поскольку он написан исключительно на JavaScript, CSS и HTML. Из внешних источников используется только Font Awesome CSS для клавиш навигации, но при желании их тоже можно заменить на собственные.

Ссылка на полный код в Codepen https://codepen.io/sergejkravchen2/pen/abVqxGv

Структура HTML

В HTML загрузите Reset CSS , чтобы очистить форматирование HTML-элементов в браузере по умолчанию. Аналогичным образом загрузите Font Awesome CSS для значков, добавив следующие ссылки CDN в тег заголовка вашей веб-страницы.

Нам нужен элемент div , в котором календарь будет отображаться динамически. Создайте элемент div с именем класса calendar-wrapper , разместите кнопки смены месяца «следующий/предыдущий» и элемент div с идентификатором divCal .

Предыдущий  

Не забудьте добавить ссылку на будущий файл .js , где будет основной функционал.

Вы можете разместить приведенную выше HTML-структуру в любом месте вашей веб-страницы/приложения, где вы хотите создать виджет календаря.

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека фронтендера»

Создание стилей CSS

После создания оболочки в HTML пришло время настроить макет календаря. Выберите класс calendar-wrapper и определите его ширину, поля, отступы и свойства границы следующим образом. Вы можете установить собственный цвет фона по вашему выбору.

.calendar-wrapper

Функция календаря генерирует даты, расположенные в виде таблицы. Таким образом, вы можете легко настроить макет календаря, выбрав элемент таблицы. Ниже приведены стили по умолчанию, вы можете изменить их в соответствии с вашими потребностями.

table < clear: both; width: 100%; border: 1px solid #dcdcff; border-radius: 3px; border-collapse: collapse; color: #444; >td < height: 48px; text-align: center; vertical-align: middle; border-right: 1px solid #dcdcff; border-top: 1px solid #dcdcff; width: 14.28571429%; >thead td

Класс not-current для элемента td указывает отключенные даты в календаре. Если вы хотите скрыть эти даты, вы можете использовать свойство видимости CSS со «скрытым» значением.

td.not-current

Если вы хотите настроить текущую дату, вы можете выбрать today класс и определить для него стили CSS.

td.today

В календаре используется значок Font Awesome внутри кнопок. Эти кнопки навигации по календарю можно настроить, выбрав их по идентификатору. Вы можете установить собственный цвет фона, размер шрифта и значок для этих кнопок в соответствии с вашими потребностями.

#btnPrev < float: left; margin-bottom: 20px; >#btnPrev:before < content: '\f104'; font-family: FontAwesome; padding-right: 4px; >#btnNext < float: right; margin-bottom: 20px; >#btnNext:after < content: '\f105'; font-family: FontAwesome; padding-left: 4px; >#btnPrev, #btnNext

Также вы можете определить стиль наведения для кнопок «следующая/предыдущая».

#btnPrev:hover, #btnNext:hover

Добавляем JavaScript

На этом этапе мы можем перейти к главному и добавить функцию JavaScript календаря в свой проект перед закрытием тега body .

var Cal = function(divId) < //Сохраняем идентификатор div this.divId = divId; // Дни недели с понедельника this.DaysOfWeek = [ 'Пн', 'Вт', 'Ср', 'Чтв', 'Птн', 'Суб', 'Вск' ]; // Месяцы начиная с января this.Months =['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']; //Устанавливаем текущий месяц, год var d = new Date(); this.currMonth = d.getMonth(); this.currYear = d.getFullYear(); this.currDay = d.getDate(); >; // Переход к следующему месяцу Cal.prototype.nextMonth = function() < if ( this.currMonth == 11 ) < this.currMonth = 0; this.currYear = this.currYear + 1; >else < this.currMonth = this.currMonth + 1; >this.showcurr(); >; // Переход к предыдущему месяцу Cal.prototype.previousMonth = function() < if ( this.currMonth == 0 ) < this.currMonth = 11; this.currYear = this.currYear - 1; >else < this.currMonth = this.currMonth - 1; >this.showcurr(); >; // Показать текущий месяц Cal.prototype.showcurr = function() < this.showMonth(this.currYear, this.currMonth); >; // Показать месяц (год, месяц) Cal.prototype.showMonth = function(y, m) < var d = new Date() // Первый день недели в выбранном месяце , firstDayOfMonth = new Date(y, m, 7).getDay() // Последний день выбранного месяца , lastDateOfMonth = new Date(y, m+1, 0).getDate() // Последний день предыдущего месяца , lastDayOfLastMonth = m == 0 ? new Date(y-1, 11, 0).getDate() : new Date(y, m, 0).getDate(); var html = ''; // Запись выбранного месяца и года html += ''; html += ''; html += ''; // заголовок дней недели html += ''; > html += ''; // Записываем дни var i=1; do < var dow = new Date(y, m, i).getDay(); // Начать новую строку в понедельник if ( dow == 1 ) < html += ''; > // Если первый день недели не понедельник показать последние дни предыдущего месяца else if ( i == 1 ) < html += ''; var k = lastDayOfLastMonth - firstDayOfMonth+1; for(var j=0; j < firstDayOfMonth; j++) < html += ''; > // Если последний день месяца не воскресенье, показать первые дни следующего месяца else if ( i == lastDateOfMonth ) < var k=1; for(dow; dow < 7; dow++) < html += '
' + this.Months[m] + ' ' + y + '
'; k++; > > // Записываем текущий день в цикл var chk = new Date(); var chkY = chk.getFullYear(); var chkM = chk.getMonth(); if (chkY == this.currYear && chkM == this.currMonth && i == this.currDay) < html += ''; > else < html += ''; > // закрыть строку в воскресенье if ( dow == 0 ) < html += '
'; k++; > > i++; >while(i '; // Записываем HTML в div document.getElementById(this.divId).innerHTML = html; >; // При загрузке окна window.onload = function() < // Начать календарь var c = new Cal("divCal"); c.showcurr(); // Привязываем кнопки «Следующий» и «Предыдущий» getId('btnNext').onclick = function() < c.nextMonth(); >; getId('btnPrev').onclick = function() < c.previousMonth(); >; > // Получить элемент по id function getId(id)

Если вам нужно добавить больше функциональности, вы можете соответствующим образом изменить код. Назначение каждой переменной, объекта и функции прокомментировано, поэтому вы можете легко понять, что делает функция календаря.

Заключение

Ну вот мы наконец и перевернули наш календарь. Это довольно простой, но в то же время гибкий пример использования JS в веб-разработке. Виджет написан на чистом JS. При желании вы даже можете исключить из него Font Awesome CSS, чтобы убрать весь внешний код. Это никак не повлияет на функционал. Оформление можно сделать любым на усмотрение, а функционал календаря расширить, добавив собственные функции на ваше усмотрение.

Ссылка на полный код в codepen https://codepen.io/sergejkravchen2/pen/abVqxGv

  • https://codeconvey.com/how-to-create-a-calendar-in-html-and-css/
  • https://stackoverflow.com/questions/51014363/how-to-change-calendars-start-date-layout-from-sunday-to-monday

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *