存储窗口.innerWidth值,并计算与调整大小时的新值的差值

Store the window.innerWidth value and calculate the difference with the new value on resize?

本文关键字:小时 调整 新值 计算 innerWidth 窗口 存储      更新时间:2023-09-26

我如何存储window.innerWidth值并计算与调整大小的新值的差异?

var w;
function example {
var onResize = function () {
    w = {width: window.innerWidth || document.body.clientWidth };
if (difference of old width and this (new) width is 100) {
// then do some stuff
}
window.addEventListener('resize', onResize);
onResize();
}

解决方案是将变量存储在onResize的全局或外部,计算旧数据和新数据之间的差异,做某种条件:(old width - new width) = 100?,如果差异是100,然后做一些事情。

现在从概念上讲,我知道如何实现这一点,但我如何在JavaScript中实际实现它?

首先使用一些更好的名称和一个额外的变量作为占位符。此外,我正在向所显示的代码添加一个作用域,以便wwidth不会在此代码片段之外使用。

(function(){
    //create a closed scope to prevent naming collision        
    //store the previous value for the width
    var previousWidth = window.innerWidth || document.body.clientWidth;
    var onResize = function () {
        //calculate the current value for the width
        var currentWidth = window.innerWidth || document.body.clientWidth;
        //look to see if the change was more than 100
        //using the absolute value here is important because it ensures
        //that a change of -150 is also a difference of more than 100
        if (Math.abs(previousWidth - currentWidth) > 100 ) {
            // then do some stuff
            //change the prior width to the current for for future references
            previousWidth = currentWidth;
        }
    };
    window.addEventListener('resize', onResize);
})()

一个完整的重构。让我们研究一种更结构化的方法,在这种方法中,我们在调整大小发生时累积大小,并查看历史值。这将使我们不仅可以跟踪它是否分段移动,还可以跟踪它一般是如何移动的,可以计算速度,还可以包含一些粒度。

jsFiddle Demo

(function(){
    //create an ExecutionContext to ensure there are no
    //variable name collisions
    //store the value of the first width of the window
    var starting = getWidth();
    //make this a function since it is called so often (DRY)
    function getWidth(){
        return window.innerWidth || document.body.clientWidth;
    }
    //this is a flag to determine if a resize is currently happening
    var moving = false;
    //this value holds the current timeout value
    var tracking = null;
    //this function allows for the resizing action to throttle
    //at 450ms (to ensure that granular changes are tracked)
    function throttle(callback){
        //setTimeout returns an integer that can later be called
        //with clearTimeout in order to prevent the callback from executing
        tracking = setTimeout(function(){
            //if this executes, it is assumed that the resize has ended
            moving = false;
            //checks to ensure calling the callback wont cause an error
            if(toString.call(callback) == "[object Function]")callback();
        },450);
    }
    //simple log in here but this will allow for other code to be placed
    //to track the beginning of the resize
    function resizeStart(){
        console.log('resizing started');
    }
    //same as the start, this will execute on finish for extension
    //purposes
    function resizeEnd(){
        console.log('resizing finished');
    }
    //this will be used to test against where the resize width value
    //started at
    var beginning = getWidth();
    //this array will hold the widths of the page as measured during
    //each resize event
    var steps = [];
    //seed it with the first value right now
    var step = getWidth();
    steps.push(step);
    //these will hold the granular changes which are the differences
    //between each concurrent step, only while a resize is active
    var changes = [];
    //the resize event handler
    window.addEventListener('resize', function(){
        //if a resize event is not active then call
        //the start function, set the width of the beginning variable
        //as an anchor so to speak, and make sure to mark resize as active
        //with the moving flag
        if(!moving){
            resizeStart()
            beginning = getWidth();
            moving = true;
        }else{
            //if the resize event is already active (moving) then clear out
            //the ending time so that it can be reconstructed since
            //we are still collecting information
            clearTimeout(tracking);
        }
        //this change will be the difference between the width now
        //and the width of the last reading
        var change = getWidth() - step;
        //once the change is calculated we update the current width reading
        //of the step
        step = getWidth();
        //and then store both of them (remember changes is only populated
        //while resize is active)
        changes.push(change);
        steps.push(step);
        //this sets up the timeout as noted above
        throttle(function(){
            //the reduce is just suming, so this takes the sum of
            //the changes array
            var totalChange = changes.reduce(function(a, b) {
                return a + b;
            });
            //if the sum was positive then the resize made the window larger
            var direction = totalChange > 0 ? "larger" : "smaller";
            //the assumption if this callback function is executing is that 
            //the resize event has finished, and so the changes array 
            //is reset
            changes = [];
            //this gets back to the very original question of when
            //there had been 100 pixels of change
            if(Math.abs(totalChange) > 100){
                console.log(Math.abs(totalChange) + " pixel granular change " + direction);
            }
            //this just logs what the overall change has been this whole time
            console.log(Math.abs(steps[steps.length-1] - starting)+" pixel overall change");
            //again noting that resize has ended, reset the "anchor" width
            beginning = getWidth();
            //and finally call our ending function
            resizeEnd();
        });
    });
})()

存储当前宽度为oldWidth。在resize监听器检查当前宽度是否与oldWidth相差100px(或更多)。如果是,那么做一些事情,用当前值更新oldWidth

var oldWidth = window.innerWidth;
var onResize = function () {
var w = window.innerWidth;
    if ( Math.abs( w - oldWidth ) >= 100 ) {
    // then do some stuff
      console.log( 'diff >= 100px' );
      oldWidth = w;
    }
}
window.addEventListener('resize', onResize);
http://jsfiddle.net/xtx1L6nr/

尝试以下操作。但是要注意,当用户调整窗口大小时,"resize"事件会周期性地发送。这段代码可以检测瞬间(最小化,最大化)或非常快的大小调整——每个渲染时间比100px快。如果您想要最终调整大小的最终大小,一旦用户放手,您将需要一个超时,就像在这个问题的答案中:检测何时使用JavaScript调整窗口大小?

var previousWidth;
var detectBigChange = function () {
  var newWidth = window.innerWidth || document.body.clientWidth;
  if (!!previousWidth && Math.abs(newWidth - previousWidth) > 100) {
    console.log("Big change!");
  }
  previousWidth = newWidth;
}
window.addEventListener('resize', detectBigChange);
detectBigChange();