Календарь js

HTML

<table id="calendar">
		<thead>
			<tr>
				<td>‹</td>
				<td colspan="5"></td>
				<td>›</td>
			</tr>
			<tr>
				<td>Пн</td>
				<td>Вт</td>
				<td>Ср</td>
				<td>Чт</td>
				<td>Пт</td>
				<td>Сб</td>
				<td>Вс</td>
			</tr>
		</thead>
		<tbody></tbody>
	</table>
	<div id="calendarTable">
		<div data-dd="5" data-link="http://dbmast.ru/obnovlenie-skripta-kalendarya-dlya-vashego-sajta" data-mm="27" data-text="Некое событие" data-yyyy="2017"></div>
		<div data-dd="8" data-link="http://dbmast.ru/obnovlenie-skripta-kalendarya-dlya-vashego-sajta" data-mm="28" data-text="Другое событие" data-yyyy="2017"></div>
	</div>

CSS

#calendar {
  width: 100%;
  max-width: 300px;
  margin: 0 auto;
  padding: 3px;
  border: 1px solid #ababab;
  font: monospace;
  line-height: 1.2em;
  font-size: 15px;
  text-align: center;
}
#calendar thead tr:last-child {
  font-size: small;
  color: rgb(85, 85, 85);
}
#calendar thead tr:nth-child(1) td:nth-child(2) {
  color: rgb(50, 50, 50);
}
#calendar thead tr:nth-child(1) td:nth-child(1):hover, #calendar thead tr:nth-child(1) td:nth-child(3):hover {
  cursor: pointer;
}
#calendar tbody td {
  color: rgb(44, 86, 122);
}
#calendar tbody td:nth-child(n+6), #calendar .holiday {
  color: rgb(231, 140, 92);
}
#calendar tbody td.today {
  background: rgb(220, 0, 0);
  color: #fff;
} 
#calendar tbody td[title] {
outline: 3px solid green;
background: yellow;
cursor: help;
}
#calendar tbody td[title] a {
display: block;
}

JavaScript

function Calendar(id, year, month) {
var Dlast = new Date(year,month+1,0).getDate(),
D = new Date(year,month,Dlast),
DNlast = new Date(D.getFullYear(),D.getMonth(),Dlast).getDay(),
DNfirst = new Date(D.getFullYear(),D.getMonth(),1).getDay(),
calendar = '<tr>',
month=["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],
soob = document.querySelectorAll('#calendarTable div');;
if (DNfirst != 0) {
for(var i = 1; i < DNfirst; i++) calendar += '<td>';
}else{
for(var i = 0; i < 6; i++) calendar += '<td>';
}
for(var i = 1; i <= Dlast; i++) {
if (i == new Date().getDate() && D.getFullYear() == new Date().getFullYear() && D.getMonth() == new Date().getMonth()) {
calendar += '<td class="today">' + i;
}else{ 
calendar += '<td>' + i;
}
if (new Date(D.getFullYear(),D.getMonth(),i).getDay() == 0) {
calendar += '<tr>';
}
}
for(var i = DNlast; i < 7; i++) calendar += '<td>&nbsp;';
document.querySelector('#'+id+' tbody').innerHTML = calendar;
document.querySelector('#'+id+' thead td:nth-child(2)').innerHTML = month[D.getMonth()] +' '+ D.getFullYear();
document.querySelector('#'+id+' thead td:nth-child(2)').dataset.month = D.getMonth();
document.querySelector('#'+id+' thead td:nth-child(2)').dataset.year = D.getFullYear();
if (document.querySelectorAll('#'+id+' tbody tr').length < 6) { // чтобы при перелистывании месяцев не "подпрыгивала" вся страница, добавляется ряд пустых клеток. Итог: всегда 6 строк для цифр
document.querySelector('#'+id+' tbody').innerHTML += '<tr><td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;';
}

// абзац создаёт сообщения
for (var k = 0; k < soob.length; k++) {
if (soob[k].dataset.yyyy == D.getFullYear() && soob[k].dataset.mm - 1 == D.getMonth()) {
var mytd = document.querySelectorAll('#'+id+' tbody td');
for (var p = 0; p < mytd.length; p++) {
if (soob[k].dataset.dd == mytd[p].innerHTML) {
if (soob[k].dataset.link) {
mytd[p].innerHTML = '<a href="' + soob[k].dataset.link + '"...