【问题标题】:jQuery ui datepicker positioning problem when scrolling down webpage向下滚动网页时jQuery ui datepicker定位问题
【发布时间】:2010-05-14 14:24:39
【问题描述】:

我有一个使用多个 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 mvc
  • jquery.ui.datepicker.js (UI/API/1.8/Datepicker)

【问题讨论】:

    标签: jquery jquery-ui datepicker


    【解决方案1】:

    我也遇到了同样的问题,我用的是 IE9,但改用 document.documentElement.scrollTop 我在我的 JS 代码上编辑了以下行

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

    这是因为document.documentElement.scrollTop返回0,对我来说上面的代码解决了我的问题

    【讨论】:

    • 完全按照您的操作进行操作,但无法解决我的问题。有什么建议吗?
    • 我也没有得到 document.documentElement.scrollTop 的值。这个答案中的代码 document.body.scrollTop 解决了我对于 IE9 和 IE8 的问题。
    【解决方案2】:

    我想我已经设法解决了我的问题,但同时我想我可能在 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 论坛中有一个类似的查询:

    Click here to view

    阅读报告似乎表明该错误已在 1.8 之前的版本中修复?

    谢谢

    【讨论】:

    • 完全按照您的操作进行操作,但无法解决我的问题。有什么建议吗?
    • 恐怕我没有其他想法?我注意到其他一些答案是相当新的,所以也许他们可以提供帮助?
    • @PanadolChong 不知何故 document.documentElement.scrollTop 对我也不起作用,可能是因为它在 iframe 中,但 document.body.scrollTop 确实有效。
    【解决方案3】:

    我在 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"> 
    

    &lt;!DOCTYPE html&gt;

    成功了!!

    我删除了强制 IE 8 仿真的元标记,但保留了我对 datepicker js 文件所做的更改。我的成功可能是编辑后的 ​​js 和 doctype 更改的组合,或者只是 doctype 的更改。

    【讨论】:

    • thnkx,它也帮助了我!
    【解决方案4】:

    我在 jQuery UI 版本 1.9.2 和 IE9 中遇到了同样的问题。

    在 jQuery UI 中似乎有一个名为 _checkOffset 的函数旨在解决这个问题。它不起作用。

    它尝试使用$(document).scrollTop(),它似乎在 IE9 中总是返回 0。 当 jQuery 函数返回零时,我不得不更改函数的内容以使用 document.body.scrollTop。因此替换

    $(document).scrollTop()
    

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

    _checkOffset 中的所有位置,以便“修复”jQuery UI 并使其正常工作。

    【讨论】:

    • 可能没问题,但请注意,如果$(document).scrollTop() 正确返回零,您的逻辑|| 将计算到运算符的右侧。
    【解决方案5】:

    在 Jquery.UI 中,只需更新 _checkOffset 函数,以便在返回 offset 之前将 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;
    },
    

    【讨论】:

    • 使用此代码,我可以修复 IE9 中的问题并使用 jquery UI 1.9.2 datepicker
    【解决方案6】:

    我不确定这是否是问题所在,但您以非标准方式附加日期选择器。您无需使用 .each(); 进行迭代

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

    此外,您应该尽可能在类选择器前面放置一个标签名称,因为它会加快选择过程。

    【讨论】:

    • 感谢您提供有关使用 .each() 并始终限定标签以加快选择过程的提示。进行了这些更改后,我仍然遇到我在帖子中描述的问题。
    • 这不能解决发帖者的问题/问题。
    【解决方案7】:

    我在正在开发的应用程序上遇到了同样的问题并找到了解决方案。该应用程序没有包含正确的文档类型规范,只需将其添加到页面顶部即可。

    <!DOCTYPE html>
    

    希望这会有所帮助。

    【讨论】:

      【解决方案8】:

      嘿,这是我们可以用来解决此问题的一种技巧。

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

      试一试它对我有用:)

      【讨论】:

      • 请注意,.ui-datepicker-trigger 应替换为表单小部件的引用,例如$("#mywidget")....
      • 另外,$.browser.msie 不适用于更高版本的 jQuery - 相反,这应该可以:navigator.userAgent.match(/msie/i)
      • 另外,我发现我必须使用document.body.scrollTop 而不是$('html').scrollTop()。 (使用 IE8,可能其他版本也需要此更改。)
      【解决方案9】:

      先到这里把你的js文件格式化成Javascript Beautifier

      然后转到第 445 行

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

      【讨论】:

        【解决方案10】:

        这对我有用:

        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'
                });
            }
        });
        

        【讨论】:

          【解决方案11】:

          可以通过添加以下代码使 Datepicker-UI 弹出窗口可拖动:

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

          因为此 ID 适用于为页面上的所有弹出日期选择器创建的组件 div。而:

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

          适用于页面上的所有日期选择器(无论是弹出式还是内联式)。通过使面板可拖动,您通常可以将日期选择器放置在您想要的位置而无需滚动。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-17
            • 1970-01-01
            相关资源
            最近更新 更多