JavaScript函数节流

函数节流

  技术一般水平有限,有什么错的地方,望大家指正。

  函数节流就是节约函数的调用,让函数少执行几次,一般用在onmousemove,onresize这种我们只要稍微一动就会砰砰砰执行多次的事件处理函数上。如果处理函数很复杂有执行很多次就很耗性能关键了有的是没有必要执行的。

  我们先说一个经常遇见的情况,鼠标放在按钮上显示下拉菜单,鼠标离开下拉菜单消失,通常我们这么写:

//title表示标题元素,content表示下拉菜单
$("#title").hover(function(){
  $("#content").show();
},function(){
  $("#content").hide();
})

  当我们快速划过的时候,会看到下拉菜单会先出现然后立即隐藏传说中的闪一下,我们知道用户快速划过时一般情况下并不是要查看下拉菜单的,所以我们要避免下拉菜单闪一下的这种事,通常我们的做法就是加一个定时器:

var timer;
$("#title").hover(function(){
    timer = setTimeout(function(){
        $("#content").show();
    },100)
},function(){
    clearTimeout(timer);
    $("#content").hide();
})

  这样当我们想查看菜单时只要把鼠标放在标题元素上下拉菜单就出现了,当我们鼠标快速划过标题元素时并不会出现下拉菜单元素,避免了菜单闪一下的尴尬事。

  继续介绍函数节流。函数节流也是这个套路,假如我们想对onresize事件进行处理(假设handler是一个很复杂的处理函数):

$(window).resize(handler);
var a = 1;
function handler(){
    console.log(a++);
}

  我们在改变窗口大小的时候只要稍微动一下处理函数就会执行十几次,这其实是完全没必要的,如果处理函数有很多的DOM操作,这是很耗性能的,所以我们要尽可能的减少事件处理函数的执行次数。

  我们也像上一个例子一样使用一个定时器来实现:

$(window).resize(handler);
var a = 1;
var timer;
function handler(){
    timer&&clearTimeout(timer);
    timer = setTimeout(function(){
        console.log(a++);
    },50)
}

  在我们改变浏览器大小的过程中事件处理函数并没有执行,只有当停止时才会执行我们的处理函数。为了使用方便可以封装成一个函数:

$(function(){
    $(window).resize(function(e){
        defer(this,200,handler)(e);
    })
})
function handler(e){
    console.log(e);
}
/**
**fn表示事件处理函数
**_this表示事件处理函数中的this指向
**delay表示延迟时间
*/
function defer(_this,delay,fn){
    return function(){
        fn.timer&&clearTimeout(fn.timer);
        var arg = arguments;
        fn.timer = setTimeout(function(){
            fn.apply(_this,arg);
        },delay)
    }
} 

  这种方式在处理onresize事件上还算是实用的但是在onmousemove上就会感觉很尴尬了,对于onmousemove我们通常处理都是标识出一个物体的轨迹,如果用上面的方式那么在移动的过程中总是清除定时器导致处理函数不执行,当鼠标停止时处理函数才开始执行,就看到物体直接从起点跳到终点,过程无迹可寻!

  查看这种情况下的拖动效果

  为了记录物体运动的轨迹我们需要在一定的间隔内就执行一次onmousemove的事件处理函数:

$(function(){
    $("#demo").bind("mousedown",function(e){
        var _this = this;
        var left = $(this).offset().left;
        var top = $(this).offset().top;
        var downX = e.pageX;
        var downY = e.pageY;
        var disX = downX-left;
        var disY = downY-top;
        $(document).bind("mousemove",function(e){
            defer(_this,200,handler)(e,disX,disY);
        })
        $(this).bind("mouseup",function(e){
            handler.timer&&clearInterval(handler.timer);
            $(document).unbind("mousemove");
            $(this).unbind("mouseup");
        })
    })
})
function handler(e,disX,disY){
    var currentX = e.pageX;
    var currentY = e.pageY;
    $(this).css({"top":currentY-disY+"px","left":currentX-disX+"px"});
    console.log(1)
}
/**
**fn表示事件处理函数
**_this表示事件处理函数中的this指向
**delay表示延迟时间
**interval表示函数执行的间隔默认50ms
*/
function defer(_this,delay,fn,interval){
    return function(){
        fn.timer&&clearTimeout(fn.timer);
        var arg = arguments;
        var _interval = interval || 50;
        fn.start?"":fn.start=+new Date();
        var current = +new Date();
        if(current-fn.start>=_interval){
            fn.start = current;
            fn.apply(_this,arg);
        }else{
            fn.timer = setTimeout(function(){
                fn.apply(_this,arg);
            },delay)
        }
    }
}

  查看效果。基本使用就是这些更多知识可以在网上查询。

时间: 2024-10-29 19:06:03

JavaScript函数节流的相关文章

简述JavaScript函数节流

为什么要用函数节流 浏览器中某些计算和处理要比其他的昂贵很多.例如,DOM 操作比起非 DOM 交互需要更多的内存和 CPU 时间.连续尝试进行过多的 DOM 相关操作可能会导致浏览器挂起,有时候甚至会崩溃.尤其在 IE 中使用 onresize 事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件会连续触发.在 onresize 事件处理程序内部如果尝试进行 DOM 操作,其高频率的更改可能会让浏览器崩溃.为了绕开这个问题,你可以使用定时器对该函数进行节流. 常见的有:重新调整浏览器窗口

再谈javascript函数节流

之前写过但是不记得在哪了,今天同事要一个滑到页面底部加载更多内容的效果,又想起了这玩意儿,确实挺实用和常用的,谨此记之. 函数节流从字面上的意思就是节约函数的执行次数,其实现的主要思想是通过定时器阻断函数的连续执行,尤其适合用在频繁操作,比如window的resize和scroll事件等. window的默认scroll事件间隔时间大概只有十几毫秒,如果频繁的scroll,然后去请求,然后渲染,对性能肯定有很大的影响. 大概模式: var processor = { timer: null, p

JavaScript函数节流与函数去抖

介绍 首先解释一下这两个概念: 函数节流(throttle):是让一个函数无法在很短的时间间隔内连续调用,当上一次函数执行后过了规定的时间间隔,才能进行下一次该函数的调用. 函数去抖(debounce):让一个函数在一定间隔内没有被调用时,才开始执行被调用方法. 两个方法都是用来提升前端性能,减轻浏览器压力. 应用 理解起来有点费力,通过应用来理解就轻松了.通常,我们会在有用户交互参与的地方添加事件,而往往这种事件会被频繁触发. 想象一下窗口的resize事件或者是一个元素的onmousemov

JavaScript函数节流和函数防抖的原理与区别

一.概念解释 ?函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.?大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变化,当高频率的扫描,人类是感觉不出来的.反而形成一种视觉效果,就是一张图.就像高速旋转的风扇,你看不到扇叶,只看到了一个圆一样.?同理,可以类推到js代码.在一定时间内,代码执行的次数不一定要非常多.达到一定频率就足够了.因为跑得越多,带来的效果也是一样.倒不如,把js代码的执行次数控制在合理的范围.

JavaScript函数节流和函数防抖之间的区别

一.概念解释 ?函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.?大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变化,当高频率的扫描,人类是感觉不出来的.反而形成一种视觉效果,就是一张图.就像高速旋转的风扇,你看不到扇叶,只看到了一个圆一样.?同理,可以类推到js代码.在一定时间内,代码执行的次数不一定要非常多.达到一定频率就足够了.因为跑得越多,带来的效果也是一样.倒不如,把js代码的执行次数控制在合理的范围.

JavaScript 函数节流和函数去抖

概念 函数防抖(debounce) 当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间 函数节流(throttle) 预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期 函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象. 函数防抖(debounce) 如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行

JavaScript 函数节流

其实最早看设计模式是单纯的了解js语言本身;所以看了理解了之后还是容易忘记;可能之后实际的工作需要才能记住吧; 看下面:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0&q

javascript函数节流(throttle)与函数去抖(debounce)

throttle 等时间 间隔执行函数. debounce 时间间隔 t 内若再次触发事件,则重新计时,直到停止时间大于或等于 t 才执行函数. 1.throttle函数的简单实现 function throttle(fn, threshhold, scope) { threshhold || (threshhold = 250); var last, timer; return function () { var context = scope || this; var now = +new

浅谈javascript的函数节流

什么是函数节流? 介绍前,先说下背景.在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在一个正常的操作中,都有可能在一个短的时间内触发非常多次事件绑定程序.而大家知道,DOM操作时很消耗性能的,这个时候,如果你为这些事件绑定一些操作DOM节点的操作的话,那就会引发大量的计算,在用户看来,页面可能就一时间没有响应,这个页面一下子变卡了变慢了.甚至在IE下,如果你绑定的resize事件进行