Запретить выделение объекта

187
24 сентября 2018, 03:20

При создании календаря те дни недели, которые не входят в текущий месяц у меня создаются как просто пустые ячейки таблицы. Но на эти пустые ячейки действуют все события: hover, click и т.д. Проблема в том можно ли как-то сделать так, что если ячейка пустая на нее нельзя кликнуть и выделить?

$(document).ready(function() { 
		$("#table td").click(function() { 
			var selected = $(this).hasClass("selected"); 
				$("#table td").removeClass("selected"); 
				if(!selected) 
            $(this).addClass("selected"); 
			 
			}); 
		}); 
var day = ['пн', 'вт', 'ср', 'чт', 'пт', 'сб', 'вс']; 
var month = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май','Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']; 
for (var i = 0; i < 12; i++) { 
    var option = document.createElement("option"); 
		option.value = i; 
    	option.text = month[i]; 
    	monthList.appendChild(option); 
	}	 
	for (var i = 1940; i < 2100; i++) { 
    	var option = document.createElement("option"); 
    	option.value = i; 
    	option.text = i; 
    	yearList.appendChild(option); 
	} 
var currentDate = new Date(); 
var today = currentDate.getDate(); 
var currentMonth = currentDate.getMonth(); 
var currentYear = currentDate.getFullYear(); 
var calendarDate = new Date(); 
var calendarMonth = calendarDate.getMonth(); 
var calendarYear = calendarDate.getFullYear(); 
var tElement=document.createElement('table'); 
tElement.id = 'table'; 
document.getElementById('tableDiv').appendChild(tElement); 
for(var i = 0; i < day.length; i ++){ 
	var th=document.createElement('th'); 
	th.innerHTML = day[i]; 
	document.getElementById('table').appendChild(th); 
} 
 
var trs=[],tds=[]; 
monthList.value = calendarMonth; 
yearList.value = calendarYear; 
 
function changeTable(calendarYear, calendarMonth) 
{ 
    var d = new Date(calendarYear, calendarMonth, 1); 
    var date = new Date(); 
    var t = d.getDay() - 1; 
    if(t < 0) 
        t = 6; 
    var a = 0; 
    while(d.getMonth() === calendarMonth || a<trs.length) 
    { 
        if(trs[a]===undefined) 
            trs[a]=document.createElement('tr'); 
        var i = 0; 
        while(i < 7) 
        { 
            if(tds[a*7+i]===undefined) 
                tds[a*7+i]=document.createElement('td'); 
		    if(a == 0 && i < t || d.getMonth() != calendarMonth) 
		        tds[a*7+i].innerHTML = ''; 
            else 
            { 
                if(String(d.getDate()).length==1) 
                    tds[a*7+i].innerHTML = d.getDate(); 
                else tds[a*7+i].innerHTML = d.getDate(); 
                tds[a*7+i].style="text-align: center"; 
                d.setDate(d.getDate() + 1); 
		    } 
            trs[a].appendChild(tds[a*7+i]); 
            i++; 
        } 
        document.getElementById('table').appendChild(trs[a]); 
        tElement.appendChild(trs[a]); 
        a++; 
	} 
	var count = 0; 
	for(var i = 0; i < 7; i++){ 
		if(tds[i].innerHTML == '') 
			count++; 
	} 
	if(monthList.value == currentMonth && yearList.value == currentYear) 
		tds[today + count - 1].style = "border: 1px solid #A5B5BC; border-radius: 50%"; 
	$("#table td").removeClass("selected"); 
} 
changeTable(calendarYear,calendarMonth); 
prevMonth.onclick=function() 
{ 
    if(monthList.value == 0){ 
    	yearList.value--; 
    	monthList.value = 11; 
    	changeTable(yearList.value, monthList.value); 
    }else{ 
    	monthList.value--; 
    	changeTable(yearList.value, monthList.value); 
    } 
} 
 
nextMonth.onclick=function() 
{ 
	if(monthList.value == 11){ 
    	yearList.value++; 
    	monthList.value = 0; 
    	changeTable(yearList.value, monthList.value); 
    }else{ 
    	monthList.value++; 
    	changeTable(yearList.value, monthList.value); 
    } 
}
th{ 
	vertical-align: middle; 
	color: #8b9295; 
	font:normal normal 14px 'Open Sans',Arial,sans-serif; 
	font-weight: bold; 
} 
 
td:hover{ 
	border-radius: 50%; 
	background-color: #e4f2fd; 
} 
 
td.selected {  
    border-radius: 50%; 
	background-color: #1A7FD4; 
	color: #FFFFFF;	 
} 
#tableDiv{ 
	border: 1px solid #FFFFFF; 
	width: 280px; 
	height: 280px; 
	background: #FFFFFF; 
	text-align: center; 
    border-radius: 0 0 4px 4px; 
    font:normal normal 14px 'Open Sans',Arial,sans-serif; 
    box-shadow: 0 14px 14px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); 
 
   
} 
#table{ 
	width: 280px; 
	height: 280px; 
	background: #FFFFFF; 
	font:normal normal 14px 'Open Sans', Arial ,sans-serif; 
}
<html lang="en"> 
<head> 
	<meta charset="utf-8"> 
	<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
	<link href='style.css' rel='stylesheet' type='text/css'> 
	 
</head> 
 
<body> 
	<div id = "headDiv">	 
			<input type="button" align="left" id="prevMonth"  value="&#8249;"> 
				<select id = "monthList" onchange="changeTable(yearList.value, monthList.value)"></select> 
				<select id = "yearList"  onchange="changeTable(yearList.value, monthList.value)"></select> 
			<input type = "button" align="right" id="nextMonth"  value="&#8250;"> 
	</div> 
		<div id = "tableDiv">		 
		</div>	 
<script src = 'main.js'></script>		 
</body> 
</html>

Answer 1

Допишите неприменение этой функции к классу (например .empty)

$("#table td:not(.empty)").click(function() {
    var selected = $(this).hasClass("selected");
    $("#table td").removeClass("selected");
    if(!selected)
        $(this).addClass("selected");       
});

И при создании элемента, если он пустой, допишите к нему необрабатываемый класс (например .empty)

tds[a*7+i]=document.createElement('td');
        if(a == 0 && i < t || d.getMonth() != calendarMonth){
            tds[a*7+i].innerHTML = '';
            tds[a*7+i].addClass('empty');
        }

Так же измените стиль

td:not(.empty){
    ...
}

Если же требуется очищать классы при смене месяца:

$('#nextMonth, #prevMonth').on('click', function(){
    $('#table td').removeClass('empty');
});
Answer 2

Это можно на css реализовать при помощи псевдокласса :empty и свойства pointer-events :

$(document).ready(function() { 
  $("#table td").click(function() { 
    var selected = $(this).hasClass("selected"); 
    $("#table td").removeClass("selected"); 
    if (!selected) 
      $(this).addClass("selected"); 
 
  }); 
}); 
var day = ['пн', 'вт', 'ср', 'чт', 'пт', 'сб', 'вс']; 
var month = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']; 
for (var i = 0; i < 12; i++) { 
  var option = document.createElement("option"); 
  option.value = i; 
  option.text = month[i]; 
  monthList.appendChild(option); 
} 
for (var i = 1940; i < 2100; i++) { 
  var option = document.createElement("option"); 
  option.value = i; 
  option.text = i; 
  yearList.appendChild(option); 
} 
var currentDate = new Date(); 
var today = currentDate.getDate(); 
var currentMonth = currentDate.getMonth(); 
var currentYear = currentDate.getFullYear(); 
var calendarDate = new Date(); 
var calendarMonth = calendarDate.getMonth(); 
var calendarYear = calendarDate.getFullYear(); 
var tElement = document.createElement('table'); 
tElement.id = 'table'; 
document.getElementById('tableDiv').appendChild(tElement); 
for (var i = 0; i < day.length; i++) { 
  var th = document.createElement('th'); 
  th.innerHTML = day[i]; 
  document.getElementById('table').appendChild(th); 
} 
 
var trs = [], 
  tds = []; 
monthList.value = calendarMonth; 
yearList.value = calendarYear; 
 
function changeTable(calendarYear, calendarMonth) { 
  var d = new Date(calendarYear, calendarMonth, 1); 
  var date = new Date(); 
  var t = d.getDay() - 1; 
  if (t < 0) 
    t = 6; 
  var a = 0; 
  while (d.getMonth() === calendarMonth || a < trs.length) { 
    if (trs[a] === undefined) 
      trs[a] = document.createElement('tr'); 
    var i = 0; 
    while (i < 7) { 
      if (tds[a * 7 + i] === undefined) 
        tds[a * 7 + i] = document.createElement('td'); 
      if (a == 0 && i < t || d.getMonth() != calendarMonth) 
        tds[a * 7 + i].innerHTML = ''; 
      else { 
        if (String(d.getDate()).length == 1) 
          tds[a * 7 + i].innerHTML = d.getDate(); 
        else tds[a * 7 + i].innerHTML = d.getDate(); 
        tds[a * 7 + i].style = "text-align: center"; 
        d.setDate(d.getDate() + 1); 
      } 
      trs[a].appendChild(tds[a * 7 + i]); 
      i++; 
    } 
    document.getElementById('table').appendChild(trs[a]); 
    tElement.appendChild(trs[a]); 
    a++; 
  } 
  var count = 0; 
  for (var i = 0; i < 7; i++) { 
    if (tds[i].innerHTML == '') 
      count++; 
  } 
  if (monthList.value == currentMonth && yearList.value == currentYear) 
    tds[today + count - 1].style = "border: 1px solid #A5B5BC; border-radius: 50%"; 
  $("#table td").removeClass("selected"); 
} 
changeTable(calendarYear, calendarMonth); 
prevMonth.onclick = function() { 
  if (monthList.value == 0) { 
    yearList.value--; 
    monthList.value = 11; 
    changeTable(yearList.value, monthList.value); 
  } else { 
    monthList.value--; 
    changeTable(yearList.value, monthList.value); 
  } 
} 
 
nextMonth.onclick = function() { 
  if (monthList.value == 11) { 
    yearList.value++; 
    monthList.value = 0; 
    changeTable(yearList.value, monthList.value); 
  } else { 
    monthList.value++; 
    changeTable(yearList.value, monthList.value); 
  } 
}
th { 
  vertical-align: middle; 
  color: #8b9295; 
  font: normal normal 14px 'Open Sans', Arial, sans-serif; 
  font-weight: bold; 
} 
 
td:hover { 
  border-radius: 50%; 
  background-color: #e4f2fd; 
} 
 
td.selected { 
  border-radius: 50%; 
  background-color: #1A7FD4; 
  color: #FFFFFF; 
} 
 
#tableDiv { 
  border: 1px solid #FFFFFF; 
  width: 280px; 
  height: 280px; 
  background: #FFFFFF; 
  text-align: center; 
  border-radius: 0 0 4px 4px; 
  font: normal normal 14px 'Open Sans', Arial, sans-serif; 
  box-shadow: 0 14px 14px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); 
} 
 
#table { 
  width: 280px; 
  height: 280px; 
  background: #FFFFFF; 
  font: normal normal 14px 'Open Sans', Arial, sans-serif; 
} 
 
 
/*Магия*/ 
 
td:empty { 
  pointer-events: none; 
}
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
<div id="headDiv"> 
  <input type="button" align="left" id="prevMonth" value="&#8249;"> 
  <select id="monthList" onchange="changeTable(yearList.value, monthList.value)"></select> 
  <select id="yearList" onchange="changeTable(yearList.value, monthList.value)"></select> 
  <input type="button" align="right" id="nextMonth" value="&#8250;"> 
</div> 
<div id="tableDiv"> 
</div>

READ ALSO
Как проверить видимость элемента jquery?

Как проверить видимость элемента jquery?

Привел тестовый пример с сайта для удобстваВроде бы всё норм: нажатие на кнопку корзины и появление счетчика товаров

181
setTimeout и clearTimeout

setTimeout и clearTimeout

При наведении на div c меню, фон вокруг затемняется, но если проводить так много раз, mouseenter & mouseleave из дива, начинает моргатьРешил установить...

179
Как сделать что бы iframe не грузился сразу?

Как сделать что бы iframe не грузился сразу?

Есть три таба в каждом будет ифрейм и надо что бы при нажатии они прогружались а не сразу при входе на сайт Возможно ли это?

159