Проблема позиционирования 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 -->
<% } %> 

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

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

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

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

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

Я использую:

  • IE7
  • asp.net мвк
  • jquery.ui.datepicker.js (UI/API/1.8/Datepicker)

person Alex P    schedule 14.05.2010    source источник


Ответы (11)


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

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

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

person Christian Suarez    schedule 13.11.2012
comment
следуйте именно тому, что вы сделали, но не можете решить мою проблему. Любое предложение? - person Panadol Chong; 24.03.2014
comment
Я также не получал значения для document.documentElement.scrollTop. Часть кода document.body.scrollTop в этом ответе решила мою проблему для IE9 и IE8. - person j4v1; 16.07.2015

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

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

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

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

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

_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?

Спасибо

person Alex P    schedule 21.05.2010
comment
следуйте именно тому, что вы сделали, но не можете решить мою проблему. Любое предложение? - person Panadol Chong; 24.03.2014
comment
Боюсь, у меня нет других идей? Я отмечаю, что некоторые другие ответы появились довольно недавно, поэтому, возможно, они могут помочь? - person Alex P; 24.03.2014
comment
@PanadolChong Почему-то document.documentElement.scrollTop у меня тоже не работал, может быть потому, что он был в iframe, но document.body.scrollTop работал. - person gbs; 17.09.2014

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

Сначала я попытался принудительно эмулировать IE 8 с помощью метатега.

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

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

Затем я отредактировал файл jquery.ui.datepicker.js, как было предложено, чтобы отрегулировать высоту позиции с учетом прокрутки. Это тоже не сработало.

Наконец, я изменил свой тип документа с

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

to

<!DOCTYPE html>

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

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

person humbolight    schedule 12.10.2012
comment
спс, мне тоже помогло! - person vladimir; 27.04.2015

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

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

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

$(document).scrollTop()

с участием

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

везде в _checkOffset, чтобы «исправить» пользовательский интерфейс jQuery и заставить его работать правильно.

person nanoscopic    schedule 04.12.2012
comment
Вероятно, все в порядке, но обратите внимание, что ваш логический || будет оценивать правую часть оператора в случае, если $(document).scrollTop() правильно возвращает ноль. - person Madbreaks; 06.11.2013

В 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;
},
person David Moore    schedule 11.07.2014
comment
используя этот код, я могу решить проблему в IE9 и с помощью jquery UI 1.9.2 datepicker - person Mallikarjuna Reddy; 13.02.2015

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

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

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

person Quasipickle    schedule 14.05.2010
comment
Спасибо за советы по использованию .each() и всегда уточняйте тег, чтобы ускорить процесс выбора. После внесения этих изменений у меня все еще есть проблема, которую я описал в своем посте. - person Alex P; 14.05.2010
comment
Это не касается вопроса/проблемы плакатов. - person andora; 01.09.2011

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

<!DOCTYPE html>

Надеюсь это поможет.

person Jeffrey Cobb    schedule 21.06.2011

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

$(".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); 
}
}); 

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

person Abhishek    schedule 04.06.2013
comment
Обратите внимание, что .ui-datepicker-trigger следует заменить любой ссылкой на ваш виджет формы, например. $("#mywidget").... - person fooquency; 11.11.2013
comment
Также $.browser.msie не будет работать с более поздними версиями jQuery — вместо этого должно работать это: navigator.userAgent.match(/msie/i) - person fooquency; 11.11.2013
comment
Кроме того, я обнаружил, что должен использовать document.body.scrollTop, а не $('html').scrollTop(). (При использовании IE8, возможно, другие выпуски также нуждаются в этом изменении.) - person fooquency; 11.11.2013

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

затем перейдите к строке № 445

k = k + document.body.scrollTop;
change this line as 
k = k ;
person sanjay    schedule 08.05.2015

Это сработало для меня:

beforeShow: function(input, inst) {
    inst.dpDiv.css({
    marginTop: $('body').scrollTop() + 'px'
});

поэтому окончательный код будет:

$(this).datepicker({
    dateFormat: 'dd M yy',
    showOn: 'button',
    buttonImage: '/Images/datepickericon.png',
    buttonImageOnly: true,
    beforeShow: function(input, inst) {
        inst.dpDiv.css({
            marginTop: $('body').scrollTop() + 'px'
        });
    }
});
person Carlos Campos    schedule 04.06.2021

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

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

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

$(".ui-datepicker").draggable()

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

person andora    schedule 01.09.2011