【问题标题】:Detect a window width change but not a height change检测窗口宽度变化但不检测高度变化
【发布时间】:2012-05-31 19:28:03
【问题描述】:

我正在使用.resize() 函数来检测窗口大小调整事件,但这会检测高度和宽度的变化。

有什么方法可以检测到只是宽度变化而不是高度变化?

【问题讨论】:

    标签: jquery responsive-design resize jquery-events


    【解决方案1】:
    var width = $(window).width();
    $(window).on('resize', function() {
      if ($(this).width() !== width) {
        width = $(this).width();
        console.log(width);
      }
    });
    

    【讨论】:

    • 有没有办法只在宽度发生变化且小于像素值时才采取行动?例如。 if ($(window).width()
    • 上面的代码可以工作,但它的性能并不理想。 jQuery 窗口对象被创建多次,即使它可以只创建一次。窗口的新宽度也被无意义地计算了多次。
    • 最好使用仅在用户为done resizing 时触发的侦听器。
    • 这实际上并不检查每次调整大小时窗口宽度是否发生变化......它只是将新窗口宽度与“原始”窗口宽度进行比较。因此,第二次和第三次调整大小时,您并没有与真正的“最后”宽度进行比较。您需要将当前窗口宽度设置为某个局部状态变量,并在每次调整大小时检查它,并在宽度最终改变时更新它。
    • 应该是 !== 而不是 !=
    【解决方案2】:

    您可以检测这两个事件并在宽度变化时执行代码:

    var lastWidth = $(window).width();
    
    $(window).resize(function(){
       if($(window).width()!=lastWidth){
          //execute code here.
          lastWidth = $(window).width();
       }
    })        
    

    您可能需要检查事件去抖动。

    去抖动强制一个函数在没有被调用的情况下经过一定的时间后才被再次调用。就像“只有在 100 毫秒没有被调用的情况下才执行这个函数。


    阅读更多:


    【讨论】:

      【解决方案3】:

      即使已经有几个可行的解决方案的答案,这种任务对性能至关重要(在用户调整窗口大小时会触发多次调整窗口大小事件)所以我强烈建议您注意性能.请看下面的优化代码:

      /* Do not waste time by creating jQuery object from window multiple times.
       * Do it just once and store it in a variable. */
      var $window = $(window);
      var lastWindowWidth = $window.width();
      
      $window.resize(function () {
          /* Do not calculate the new window width twice.
           * Do it just once and store it in a variable. */
          var windowWidth = $window.width();
      
          /* Use !== operator instead of !=. */
          if (lastWindowWidth !== windowWidth) {
              // EXECUTE YOUR CODE HERE
              lastWindowWidth = windowWidth;
          }
      });
      

      另外,您可能有兴趣检查 Debounce / Throttle 模式 - 在这种情况下,它们会极大地提高性能。

      【讨论】:

        【解决方案4】:

        也可以使用这个小型 jQuery 插件:https://github.com/adjohnson916/jquery-resize-dimension

        让您自己的代码更具可读性:

        ResizeDimension.bind('width');
        $(window).on('resize-width', function () {
          console.log('resize-width event');
        });
        

        或者只是:

        $(window).resizeDimension('width', function () {
          console.log('resize-width event');
        });
        

        【讨论】:

          【解决方案5】:

          @nachtigall 提供的链接已损坏,因此我找到了另一个具有相同库的链接,这帮助我解决了我的问题: resize-dimension.js

          解决方案示例如下: 导入库:

          <script src="./resize-dimension.js"></script>
          

          创建脚本:

          <script type="text/javascript">
                  ResizeDimension.bind('width');
                  $(window).on('resize-width', function () {
                      //alert(window);
                      ForResize();
                  });
           </script>
          

          当浏览器调整大小时,函数ForResize() 被触发,虽然在这种情况下,IE 处理它比其他浏览器更好,但是,在我的情况下,它在移动设备上运行良好,在滚动时触发事件页面,取决于移动浏览器,它可以隐藏地址栏,这会影响浏览器的大小。实施该库有帮助!

          我使用了here 提供的计数器/计时器,并根据我的需要对其进行了修改。以下是我必须创建的关键脚本:

          <script type="text/javascript">
              function RefreshWidth() {
                  var _hcontainer = $("#chart_container").width();
                  var _hcontainerInt = parseInt(_hcontainer, 10);
                  $("#txChartSize").val(_hcontainerInt);
                  $("#txChartSize_1").val(_hcontainerInt);
                  $("#textWidthFire").val(_hcontainerInt);
                  DetectResizeChange();
              }
          </script>
          
          <script type="text/javascript">
              var myTimer; //also in C#
              var c = 0;
              //these functions are needed in order to fire RefreshWidth() so it will fire DetectResizeChange() after browser changes size
              function clock() {
                  //RefreshWidth();
                  myTimer = setInterval(myClock, 1000);
                  c = 3;
          
                  function myClock() {
                      document.getElementById("loadMsg").innerHTML = "Processing chart, please wait...";
                      --c; //--->>counts in reverse to resize
                      if (c == 0) {
                          RefreshWidth(); //--->>gives enough time for the width value to be refreshed in the textbox
                          clearInterval(myTimer);
                      }
          
                  }
              }
          
              //detects size change on the browser
              function DetectResizeChange() {
                  var _NoDataAvailable = $('#txNoDataAvailable').val();
          
                  if (_NoDataAvailable != 'NoData') {
          
                      var refLine = $("#refLine").width();
          
                      var _hcontainer = $("#chart_container").width();
                      var _width = _hcontainer;
          
                      var _hcontainerInt = parseInt(_hcontainer, 10);
          
                      $("#txChartSize").val(_hcontainerInt);
                      $("#textWidthFire").val(_hcontainerInt);
                      $('#msgAdjustView').show();
          
                      $("#msgAdjustView").text("Loading data and adjusting chart view, please wait...");
                      $('.modal').show();
          
                      var checkOption = document.getElementById('lbViewingData').value;
                      var button;
                      var btnWidth;
                      btnWidth = document.getElementById('btnStopTimer');
                      if (checkOption == 'Option 1') {
                          button = document.getElementById('firstTab');
                      } else if (checkOption == 'Option 2') {
                          button = document.getElementById('secondTab');
                      } else if (checkOption == 'Option 3') {
                          button = document.getElementById('thirdTab');
                      }
                      button.click();
                  }
              }
          </script>
                  <script type="text/javascript">
                      function ForResize() {
                          var _NoDataAvailable = $('#txNoDataAvailable').val();
          
                          if (_NoDataAvailable != 'NoData') {
                              clock();
                              document.getElementById('loadMsg').innerHTML = 'Resizing chart in progress...';
                          }
                      }
          
          </script>
          

          如果库的链接再次断开,这里是来自同一来源的代码(resize-dimension.js):

          (function (root, factory) {
            var moduleName = 'ResizeDimension';
            if (typeof define === 'function' && define.amd) {
              define(['jquery'], function ($) {
                  return (root[moduleName] = factory($));
              });
            } else {
              root[moduleName] = factory(root.$);
            }
          }(this, function ($) {
          
            var $window = $(window);
          
            var ResizeDimension = function ($el, dimension, handler, options) {
          
              if (! (this instanceof ResizeDimension)) {
                return new ResizeDimension($el, dimension, handler, options);
              }
          
              this.$el = $el;
          
              this.init(dimension, handler, options);
          
              return this;
            };
          
            /**
             * Stub - overridden on #init()
             */
            ResizeDimension.prototype.onResize = function () {};
          
            ResizeDimension.bound = {};
          
            ResizeDimension.bind = function (dimension, options) {
              if (ResizeDimension.bound[dimension]) return;
              ResizeDimension.bound[dimension] = true;
              $window.resizeDimension(dimension, function () {
                $window.trigger('resize-' + dimension);
              }, options);
            };
          
            ResizeDimension.prototype.init = function (dimension, handler, options) {
          
              if (typeof dimension === 'object') {
                options = dimension;
                dimension = options.dimension;
                handler = options.handler;
              }
          
              options = $.extend({}, options);
              options.dimension = dimension;
              options.handler = handler;
          
              this.options = options;
          
              if ($.isFunction(options.changed)) {
                this.changed = options.changed;
              }
          
              this.dimension = this.normalize(options.dimension);
              this.handler = options.handler;
              this.previousValue = this.value();
          
              var proxied = $.proxy(this.handle, this);
              if (options.throttler) {
                this.onResize = options.throttler(proxied);
              }
              else {
                this.onResize = proxied;
              }
            };
          
            ResizeDimension.prototype.normalize = function (dimension) {
              return dimension;
            };
            ResizeDimension.prototype.changed = function (previous, current) {
              return previous !== current;
            };
          
            ResizeDimension.prototype.value = function (e) {
              return this.$el[this.dimension]();
            };
          
            ResizeDimension.prototype.handle = function (e) {
              var currentValue = this.value();
              if (this.changed(this.previousValue, currentValue)) {
                this.previousValue = currentValue;
                return this.handler.call(this.$el, e);
              }
            };
          
            var $resizeDimension = function () {
              var args = Array.prototype.slice.call(arguments);
              return this.each( function() {
                var $el = $(this);
                args = [$el].concat(args);
                var instance = ResizeDimension.apply(null, args);
                $el.on('resize', $.proxy(instance.onResize, instance));
              });
            };
          
            $.fn.resizeDimension = $resizeDimension;
          
            return ResizeDimension;
          
          }));
          

          【讨论】:

          • 请不要只发布一些工具或库作为答案。至少在答案本身中展示how it solves the problem。
          • 我很抱歉!我添加了详细信息。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-17
          • 2011-01-11
          • 1970-01-01
          • 2021-06-18
          • 2017-04-01
          • 2023-04-05
          • 2012-02-20
          相关资源
          最近更新 更多