проблема позиционирования jQuery ui datepicker при прокрутке вниз веб-страницы

у меня есть веб-страница, которая использует несколько экземпляров jQuery ui datepicker. Моя веб-страница будет отображать ~80 записей, которые выходят за рамки одного скриншота.

<% foreach (var record in Model) { %>
    <div class="recordname"><%=record.name%></div>
    <%=Html.TextBox("DateTimePicker", null, new { @class = "date-pick" } )%>
    // <-- additional html here -->
<% } %> 

Я установил значения по умолчанию для моего datepicker следующим образом:

    $(".date-pick").each(function() {
    $(this).datepicker({
        dateFormat: 'dd M yy',
        showOn: 'button',
        buttonImage: '/Images/datepickericon.png',
        buttonImageOnly: true
        });
    });

при первой загрузке страницы, если я нажму любой значок datepicker, который отображается на экране (т. е. без прокрутки) затем datepicker появляется, как ожидалось.

однако, если я прокручиваю страницу вниз, а затем щелкните значок datepicker, datepicker не отображается в окне экрана, а вместо этого отображается в верхней части экрана.

есть идеи, как это решить?

Я использую:

  • IE7
  • asp.net mvc
  • С помощью jQuery.пользовательский интерфейс.элемент управления datepicker.js (UI/API/1.8/Datepicker)

10 ответов


у меня тоже была такая же проблема, я использую IE9, но вместо этого использую document.documentElement.scrollTop я редактирую следующую строку в моем коде JS

$.datepicker._pos[1] += input.offsetHeight + document.body.scrollTop;

Это так document.documentElement.scrollTop возвращает 0, для меня приведенный выше код решает мои проблемы


Я думаю, что мне удалось решить мою проблему, но в то же время мне кажется, я обнаружил баг (?) в коде datepicker пользовательского интерфейса jquery.

прежде чем я пойду дальше, позвольте мне просто сказать, что я новичок в jQuery / javascript и был бы признателен за любой вклад ниже.

чтобы повторить проблему, я использую asp.net mvc и я пытаемся показать ~80 datepickers на странице. Для любого datepicker в начальном окне просмотра позиция datepickers прекрасна. Однако, когда я прокручиваю вниз datepickers по-прежнему отображаются в верхней части экрана.

Я начал просматривать исходный код и сделать некоторые отладки. Я заметил, что степень, в которой datepicker был смещен к верхней части экрана, была прямо пропорциональна сумме, на которую я прокрутил, т. е. больше прокрутки = большее смещение.

ключевая проблема в коде, который я нашел (см. ниже), заключается в том, что когда код работает, где разместить datepicker, он не учитывает как далеко вниз по экрану прокрутил пользователь:

_showDatepicker: 
function(input) { 
      input = input.target || input;
      //....more code...

      if (!$.datepicker._pos) { // position below input
      $.datepicker._pos = $.datepicker._findPos(input);
      $.datepicker._pos[1] += input.offsetHeight; //add the height
       }

в последней строке метод offsetHeight не учитывает, сколько вы прокрутили вниз по экрану.

Если вы обновите эту строку до следующего, это решит проблему, которую я поднял:

  $.datepicker._pos[1] += input.offsetHeight + document.documentElement.scrollTop; //add the height 

Это просто получает положение полосы прокрутки и добавляет его в offsetHeight, чтобы получить правильное положение.

в интересах полного раскрытия я не совсем уверен, почему это работает и был бы признателен за некоторое понимание.

Я потратил ~ 3 дня на эту проблему и исследовал интернет, и это лучшее, что я могу придумать.

интересно, что аналогичный запрос был на форумах jquery:

Нажмите здесь, чтобы просмотреть

чтение отчета, казалось, предполагало, что ошибка была исправлена в предыдущей версии до 1.8?

спасибо


у меня были эти проблемы, а также в IE 9 и не могу поблагодарить вас за вашу коллективную помощь. Chrome 22.0.1229.94 m и FF 15.0.1 не показывали эту проблему для меня.

Я сначала попытался заставить эмуляцию IE 8 с метатегом

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" /> 

безрезультатно.

затем я отредактировал С помощью jQuery.пользовательский интерфейс.элемент управления datepicker.js файл, как предложено, чтобы настроить высоту позиции, учитывая прокрутку. Это тоже не сработало.

Наконец-То Я изменил мой doctype с

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 

to

<!DOCTYPE html>

, который успешно работал!!

Я удалил мета-тег, который заставил эмуляцию IE 8, но сохранил изменения, которые я внес в файл datepicker js. Мой успех может быть комбинацией отредактированного js и изменения doctype или просто изменения doctype.


я столкнулся с этой же проблемой с jQuery UI версии 1.9.2 и IE9.

в jQuery UI есть функция под названием _checkOffset это предназначено для решения этой проблемы. Это не работает.

он пытается использовать $(document).scrollTop(), который всегда, кажется, возвращает 0 в IE9. Мне пришлось изменить содержимое функции для использования document.body.scrollTop вместо этого, когда функция jQuery возвращает ноль. Таким образом, замените

$(document).scrollTop()

С

($(document).scrollTop()||document.body.scrollTop)

везде в _checkOffset для того, чтобы "исправить" jQuery UI и заставить его работать правильно.


В Jquery.UI, просто обновите функцию _checkOffset, чтобы viewHeight был добавлен в offset.top, перед возвратом смещения.
сценарий: datepicker.js

_checkOffset: function(inst, offset, isFixed) {
     var dpWidth = inst.dpDiv.outerWidth();
     var dpHeight = inst.dpDiv.outerHeight();
     var inputWidth = inst.input ? inst.input.outerWidth() : 0;
     var inputHeight = inst.input ? inst.input.outerHeight() : 0;
     var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
     var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : ($(document).scrollTop()||document.body.scrollTop));

     offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
     offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
     offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? ($(document).scrollTop()||document.body.scrollTop) : 0;

     // now check if datepicker is showing outside window viewport - move to a better place if so.
     offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
                Math.abs(offset.left + dpWidth - viewWidth) : 0);
     offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
                Math.abs(dpHeight + inputHeight) : 0);
     offset.top = offset.top + viewHeight;

     return offset;
},

Я не уверен, что это будет проблемой, но вы прикрепляете datepicker нестандартным способом. Вам не нужно повторять .each();

$("input.date-pick").datepicker({
    dateFormat: 'dd M yy',
    showOn: 'button',
    buttonImage: '/Images/datepickericon.png',
    buttonImageOnly: true
});

кроме того, вы всегда должны помещать имя тега перед селектором классов, когда это возможно, так как это ускоряет процесс выбора.


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

<!DOCTYPE html>

надеюсь, что это помогает.


Эй, вот один хак, который мы можем использовать для решения этой проблемы.

$(".ui-datepicker-trigger").on("click", function() {
var self;
if ($.browser.msie) {
self = $(this);
$("#ui-datepicker-div").hide();
setTimeout(function(){
$("#ui-datepicker-div").css({
top: self.offset().top + $('html').scrollTop() + 30
});
$("#ui-datepicker-div").show();
}, 0); 
}
}); 

попробуйте, это сработало для меня:)


сначала перейдите сюда и отформатируйте файл js в Javascript Beautifier

затем перейдите в строку no 445

k = k + document.body.scrollTop;
change this line as 
k = k ;

всплывающее окно Datepicker-UI можно сделать перетаскиваемым, добавив следующий код:

$('#ui-datepicker-div').draggable ();

поскольку этот идентификатор применяется к компоненту div, созданному для всех всплывающих datepickers на странице. В то время как:

$(".интерфейс-элемент управления datepicker").draggable ()

применяется ко всем datepickers на странице (будь то всплывающее окно или встроенный). Сделав панель перетаскиваемой, вы обычно можете разместить datepicker там, где хотите это без прокрутки.