2017-01-20 10 views
0

Я запрограммировал календарь, в котором вы можете нажать на дату, чтобы показать ее. Он отлично работает во всех браузерах, кроме Safari. Я искал ошибку в течение нескольких часов, но я не могу ее найти, мой поиск в google говорит, что мне нужно изменить формат строки даты, но я создаю объект даты непосредственно, не используя строку даты или инициализацию, поэтому должен быть другим способом. Вы нашли ошибку? Я был бы очень благодарен!Javascript - Календарь не работает на Safari

main.html:

<html> 
    <head> 
     <script language="javascript" type="text/javascript" src="functions.js"></script> 
    </head> 

    <body> 
     <script> 
      displayMyDate(); 
      calendar(); 
     </script> 
    </body> 
</html> 

functions.js:

var myDate = new Date(); 

function setStyle(id,style,value) 
{ 
    id.style[style] = value; 
} 

function opacity(el,opacity) 
{ 
     setStyle(el,"filter:","alpha(opacity="+opacity+")"); 
     setStyle(el,"-moz-opacity",opacity/100); 
     setStyle(el,"-khtml-opacity",opacity/100); 
     setStyle(el,"opacity",opacity/100); 
} 

function onCalendarClick(date) { 
    myDate = new Date(date); 
    var div = document.getElementById('myDate'); 
    if (div != null) { 
     div.innerHTML = 'Datum: ' + myDate.toLocaleDateString(); 
    } 
    onReturnToHome(); 
} 

function displayMyDate() { 
    document.write('<div id="myDate" onclick="onMyDateClick();">Datum: ' + myDate.toLocaleDateString() + '</div>'); 
} 

function calendar(date) 
{ 
    if (date == null) var date = new Date(); 
    else myDate =date; 
     var day = date.getDate(); 
     var month = date.getMonth(); 
     var year = date.getYear(); 
     if(year<=200) 
     { 
       year += 1900; 
     } 
     months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'Jully', 'August', 'September', 'October', 'November', 'December'); 
     days_in_month = new Array(31,28,31,30,31,30,31,31,30,31,30,31); 
     if(year%4 == 0 && year!=1900) 
     { 
       days_in_month[1]=29; 
     } 
     total = days_in_month[month]; 
     var date_today = day+' '+months[month]+' '+year; 
     beg_j = date; 
     beg_j.setDate(1); 
     if(beg_j.getDate()==2) 
     { 
       beg_j=setDate(0); 
     } 
     beg_j = beg_j.getDay(); 
     document.write('<table class="cal_calendar" onload="opacity(document.getElementById(\'cal_body\'),20);"><tbody id="cal_body"><tr><th colspan="7">'+date_today+'</th></tr>'); 
     document.write('<tr class="cal_d_weeks"><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr><tr>'); 
     week = 0; 
     for(i=1;i<=beg_j;i++) 
     { 
       document.write('<td class="cal_days_bef_aft">'+(days_in_month[month-1]-beg_j+i)+'</td>'); 
       week++; 
     } 
     for(i=1;i<=total;i++) 
     { 
       if(week==0) 
       { 
         document.write('<tr>'); 
       } 
       if(day==i) 
       { 
         document.write('<td class="cal_today" onClick="onCalendarClick(\''+ year + '-' + (month+1) + '-' + i + '\');">'+i+'</td>'); 
       } 
       else 
       { 
         document.write('<td onClick="onCalendarClick(\''+ year + '-' + (month+1) + '-' + i + '\');">'+i+'</td>'); 
       } 
       week++; 
       if(week==7) 
       { 
         document.write('</tr>'); 
         week=0; 
       } 
     } 
     for(i=1;week!=0;i++) 
     { 
       document.write('<td class="cal_days_bef_aft">'+i+'</td>'); 
       week++; 
       if(week==7) 
       { 
         document.write('</tr>'); 
         week=0; 
       } 
     } 
     document.write('</tbody></table>'); 
     opacity(document.getElementById('cal_body'),70); 
     return true; 
} 
+0

вы получаете какие-либо ошибки на сафари консоли? –

+0

Когда вы нажимаете на другую дату, то он показывает недопустимую дату –

+0

Использование * document.write * для написания фрагментов недопустимого HTML не является хорошей идеей, даже если в конце концов она «действительна» (например, для написания открытого тега таблицы в другом выражении для записи закрывающего тега). Гораздо лучше построить всю строку и использовать один * document.write *, когда он будет завершен.Атрибут * language * для элементов скрипта был устаревшим с HTML 4 и удалялся с тех пор. – RobG

ответ

0

onReturnToHome() Функция не определена. Это просто отсутствует в вашем js-файле?

+0

Я поставил важные детали из более крупного проекта только для показа важной части :) –

0

Помимо этой недостающей функции, я также получаю ошибки для формата даты. Кажется, что вы используете строки типа «2017-1-1» для установки новых дат. Это недопустимые форматы и не могут быть проанализированы новой Date() напрямую. Вы должны добавить ведущие нули на каждое число ниже десяти.

Так «2017-01-20» на сегодняшний день вместо «2017-1-20»

(пс: Не забывайте работать со строкой «01», потому что число 01 может быть использован в качестве восьмеричные и дают новые ошибки.)

Полный код, HTML остается таким же, как в исходном сообщении. В JS я только изменил цикл в календаре Fn:

var myDate = new Date(); 

function setStyle(id,style,value) { 
    id.style[style] = value; 
} 

function opacity(el,opacity) { 
     setStyle(el,"filter:","alpha(opacity="+opacity+")"); 
     setStyle(el,"-moz-opacity",opacity/100); 
     setStyle(el,"-khtml-opacity",opacity/100); 
     setStyle(el,"opacity",opacity/100); 
} 

function onCalendarClick(date) { 
    myDate = new Date(date); 
    var div = document.getElementById('myDate'); 
    if (div != null) { 
     div.innerHTML = 'Datum: ' + myDate.toLocaleDateString(); 
    } 
    //onReturnToHome(); 
} 

function displayMyDate() { 
    document.write('<div id="myDate" onclick="onMyDateClick();">Datum: ' + myDate.toLocaleDateString() + '</div>'); 
} 

function calendar(date) { 
    if (date == null) var date = new Date(); 
    else myDate =date; 
     var day = date.getDate(); 
     var month = date.getMonth(); 
     var year = date.getYear(); 
     if(year<=200) 
     { 
       year += 1900; 
     } 
     months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'Jully', 'August', 'September', 'October', 'November', 'December'); 
     days_in_month = new Array(31,28,31,30,31,30,31,31,30,31,30,31); 
     if(year%4 == 0 && year!=1900) 
     { 
       days_in_month[1]=29; 
     } 
     total = days_in_month[month]; 
     var date_today = day+' '+months[month]+' '+year; 
     beg_j = date; 
     beg_j.setDate(1); 
     if(beg_j.getDate()==2) 
     { 
       beg_j=setDate(0); 
     } 
     beg_j = beg_j.getDay(); 
     document.write('<table class="cal_calendar" onload="opacity(document.getElementById(\'cal_body\'),20);"><tbody id="cal_body"><tr><th colspan="7">'+date_today+'</th></tr>'); 
     document.write('<tr class="cal_d_weeks"><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr><tr>'); 
     week = 0; 
     for(i=1;i<=beg_j;i++) 
     { 
       document.write('<td class="cal_days_bef_aft">'+(days_in_month[month-1]-beg_j+i)+'</td>'); 
       week++; 
     } 
     for(i=1;i<=total;i++) 
     { 
      var dateToWrite = (i < 10) ? '0' + i : i; 
      var monthToWrite = (month + 1 < 10) ? '0' + (month + 1) : month + 1; 
       if(week==0) 
       { 
         document.write('<tr>'); 
       } 
       if(day==i) 
       { 
         document.write('<td class="cal_today" onClick="onCalendarClick(\''+ year + '-' + monthToWrite + '-' + dateToWrite + '\');">'+ dateToWrite +'</td>'); 
       } 
       else 
       { 
         document.write('<td onClick="onCalendarClick(\''+ year + '-' + monthToWrite + '-' + dateToWrite + '\');">'+ dateToWrite +'</td>'); 
       } 
       week++; 
       if(week==7) 
       { 
         document.write('</tr>'); 
         week=0; 
       } 
     } 
     for(i=1;week!=0;i++) 
     { 
       document.write('<td class="cal_days_bef_aft">'+i+'</td>'); 
       week++; 
       if(week==7) 
       { 
         document.write('</tr>'); 
         week=0; 
       } 
     } 
     document.write('</tbody></table>'); 
     opacity(document.getElementById('cal_body'),70); 
     return true; 
} 
+0

Спасибо за ваш ответ! :) Можете ли вы просто сказать мне, где вы внесли изменения, или можете опубликовать отредактированный код? я пытаюсь ввести его, он работает неправильно –

+0

Добавлен блок, который я изменил. Если вы предпочитаете, тройка может быть заменена нормальным if/else. Не забудьте также заменить i в html. – Shilly

+0

Большое вам спасибо за помощь! Но это также не работает правильно :(И я не знаю, что вы имеете в виду, что я должен заменить в html-файле, извините за мои плохие навыки: D Но я очень благодарю вас за вашу помощь! Возможно, мы нашли ошибку! –

0

Как отметил Shilly, ваша проблема связана с new Date(date) где дата является неподдерживаемый и нестандартный формат.

Как правило, вам не следует анализировать строки с помощью конструктора Date (или Date.parse), поскольку он в значительной степени зависит от реализации и несовместим между реализациями.

Например, если вы меняете в формат ISO 8601 и использование:

var date = new Date('2017-01-20') 

затем «2017-01-20» будет разобрано как UTC, так и для пользователей к западу от Гринвича дата может показаться быть на один день раньше, чем ожидалось, если вы не используете UTC для всего (и тогда вы, возможно, поймали на летнее время).

Лучше либо вручную разобрать строку, либо использовать библиотеку.

+0

Для записи, расчета всех в UTC, а затем, при необходимости, преобразования локали, это лучшая практика, на которой я работаю, поскольку вы хотите иметь возможность сравнивать даты по всему миру. – Shilly

+0

@ Shilly-sure, я не думаю, что все, что я написал, противоречит этому. – RobG

0

Проблема решена, это решение:

myDate = new Date(date.replace(/-/g, "/")); 

вместо

myDate = new Date(date); 

в функции onCalendarClick (дата)