【问题标题】:Jquery resize() causing screen flickering and div offsetJquery resize() 导致屏幕闪烁和 div 偏移
【发布时间】:2013-04-13 06:57:25
【问题描述】:

背景:

我正在尝试创建一个系统,允许使用鼠标向上滚动和鼠标向下滚动来滚动浏览一种地图,如下所示:

 -------
|       |
|   1   |
|       |
 -------
 -------    -------   -------   -------
|       |  |       | |       | |       |
|   2   |  |   3   | |   4   | |   5   |
|       |  |       | |       | |       |
 -------    -------   -------   -------
                                -------
                               |       |
                               |   6   |
                               |       |
                                -------

上面的每个框都在 javascript 中重置为浏览器的高度和宽度。当您上下滚动鼠标时,浏览器将滚动到地图中的相同位置,从 div 1 开始,然后是 2,依此类推。这个位置是通过我的滚动功能设置的,它会监听鼠标滚动并在顶部添加适当的填充,在左侧添加边距以创建上面地图的错觉。

这是它的代码:

http://codepen.io/lorenzoi/pen/mxejJ

这里是它的 javascript:

$(function(){

    $(window).on('resize', function(){
        var $divs = $('.vertical, .horizontal > div'),
        ww =  $(this).width(),
        wh =  $(this).height();

        $divs.css({
            height : wh,
            width : ww
        });

        $('.horizontal').each(function(){
            var $container = $(this),
            nbChildren = $container.children().length;
            posY = $container.offset().top,


            $container.css({
                height: ww*(nbChildren-1) + wh,
                width: ww*(nbChildren)
            });
        });
    }).trigger('resize');

    $(window).on('scroll', function(){
        var wh = $(window).height(),
        scroolTop = $(window).scrollTop();

        $('.horizontal').each(function(){
            var $container = $(this),
            posY = $container.offset().top,
            height = $container.height(),
            nbChildren = $container.children().length,
            marginMax = $container.width()/nbChildren*(nbChildren-1),
            marginL = scroolTop - posY;

            if(marginL<0) marginL = 0;
            else if (marginL>marginMax) marginL = marginMax;
            $container.css('marginLeft', -marginL);
            $container.css('paddingTop', marginL);
        });
    }).trigger('scroll');

});

问题:

调整窗口大小会创建一个奇怪的 div 偏移量,当为 div 2 到 5 调用滚动函数时,它会自行修复。在这些 div 中调整大小时,它们似乎会自行偏移,然后只有在调用滚动函数时才会修复。

.trigger('resize');应该总是被调用,是吗?我不知道为什么它只在创建滚动功能时才被调用。

如何解决这个问题?

【问题讨论】:

标签: javascript jquery resize window dom-manipulation


【解决方案1】:

使用计时器就足够了:

$(function(){
    var timeoutResize;

    $(window).on('resize', function(){
        clearTimeout(timeoutResize);
           timeoutResize = setTimeout(function(){
           var $divs = $('.vertical, .horizontal > div'),
           ww =  $(this).width(),
           wh =  $(this).height();

           $divs.css({
               height : wh,
               width : ww
           });

           $('.horizontal').each(function(){
               var $container = $(this),
               nbChildren = $container.children().length;
               posY = $container.offset().top,


               $container.css({
                   height: ww*(nbChildren-1) + wh,
                   width: ww*(nbChildren)
               });
           });
       },100);
    }).trigger('resize');

    ...

});

【讨论】:

    【解决方案2】:

    。 .您需要考虑的是,每当用户垂直调整窗口大小时,滚动位置都会受到影响,并且它也会影响您的背景滚动(因为它是基于当前滚动位置的)。

    。 .最简单的解决方法是在调整大小处理程序代码的末尾简单地调用$(window).trigger('scroll');,这样你就可以让它保持干燥。我在my CodePen fork 上进行了此更改。看看吧。

    【讨论】:

      【解决方案3】:

      如果您有一个运行过于频繁的事件处理程序,您可以像这样限制它:

      function throttle(ms, fn) {
          var allow = true;
          function enable() {
              allow = true;
          }
          return function(e) {
              if (allow) {
                  allow = false;
                  setTimeout(enable, ms);
                  fn.call(this, e);
              }
          }
      }
      

      然后在分配时将您的处理程序传递给throttle。根据您提供的第一个参数,它将返回一个最多每n 毫秒运行一次的函数。

      $(window).resize(throttle(100, function(e) {
          // do heavy work
      }));
      

      【讨论】:

      • 该问题与运行过于频繁的事件完全无关。你读过这个问题吗?
      • @DiegoNunes:这个问题在我回答很久之后才更新。最初的问题是:“我怎样才能优化 $(window).resize() 在用户滚动浏览我的 div 地图时不会不断重新计算?”
      • 哦,我明白了。很高兴在 cmets 中注意到它,然后 :)
      猜你喜欢
      • 2012-08-27
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多