zoukankan      html  css  js  c++  java
  • requestAnimationFrame节流,优化scroll和touchmove事件

    touchmove和scroll事件发生很频繁, 会比屏幕刷新率快, 导致无效的渲染和重绘。
    可以使用requestAnimationFrame来优化滚动处理, 在一帧中只进行一次重绘。

    1. onScroll用requestAnimationFrame来优化
    // rAF触发锁,必须加锁,多次调用raf,会在一帧中多次触发回调
    var ticking = false; 
     
    function onScroll(){
      if(!ticking) {
        requestAnimationFrame(realFunc);
        ticking = true;
      }
    }
     
    function realFunc(){
        // do something...
        console.log("Success");
        ticking = false;
    }
    // 滚动事件监听
    window.addEventListener('scroll', onScroll, false);
    2. 封装一个raf的动画函数
    var lock = {};
    function animationFrame (callback = (time) => {}, key = 'default') {
        if (lock[key]) { return false }
        lock[key] = true
        window.requestAnimationFrame((time) => {
            lock[key] = false
            callback(time)
        })
        return true
    }
    
    // 调用
    window.addEventListener('scroll', () => { animationFrame((time) => doAnimation(time)) })
    3. 封装一个raf的throttle方法
    var rafThrottle = function(fn) {
        var ticking = false;
        var update = function() {
            ticking = false;
            fn && fn.apply(this, arguments);
        }
    
        function requestTick() {
            if (!ticking) {
                requestAnimationFrame(update);
            }
            ticking = true;
        }
        requestTick();
    }
    4. touchmove用requestAnimationFrame优化,一帧只执行一次计算
    function drag(element) {
        var startX = 0,
            startY = 0,
            ticking = false,
            raf,
            doc = document;
    
        element.addEventListener("touchstart", function(e) {
            var e = e || window.event,
                touchs = e.touches[0];
            e.preventDefault(); //低端安卓touch事件有的导致touchend事件时效,必须开始就加 e.preventDefault();
            startX = parseInt(touchs.pageX - (element.lefts || 0));
            startY = parseInt(touchs.pageY - (element.tops || 0));
            doc.addEventListener("touchmove", update, false);
            doc.addEventListener("touchend", end, false);
        }, false);
    
        var update = function(e) {
            var e = e || window.event;
            if (e.touches.length > 1 || e.scale && e.scale !== 1) return;
            e.preventDefault();
            if (!ticking) {
                var touchs = e.changedTouches[0];
                //1先触摸移动  
                element.lefts = touchs.pageX - startX;
                element.tops = touchs.pageY - startY;
                //2交给requestAnimationFrame 更新位置
                raf = requestAnimationFrame(draw);
            }
            ticking = true;
        };
    
        var draw = function() {
            ticking = false;
            var nowLeft = parseInt(element.lefts); //滑动的距离touchmove时候,如果加阻力,可能有细小的抖动;我想应该是移动端 部分支持0.5px的缘故;parseInt的转化有点牵强;
            var nowTop = parseInt(element.tops); //滑动的距离    
            element.style.webkitTransform = element.style.transform = "translate3D(" + nowLeft + "px," + nowTop + "px,0px)";
        };
    
        var end = function() {
            var endLeft = parseInt(element.lefts); //滑动的距离    
            var endTop = parseInt(element.tops); //滑动的距离
            doc.removeEventListener("touchmove", update, false);
            doc.removeEventListener("touchend", end, false);
        }
    }
    参考:https://cloud.tencent.com/developer/article/1613039
         https://www.cnblogs.com/coco1s/p/5499469.html
         http://www.mamicode.com/info-detail-1256974.html
     
  • 相关阅读:
    (转)TextView 设置背景和文本颜色的问题
    (转)Android强制设置横屏或竖屏
    android栈和队列
    关于android开发环境中sdk和adt更新到22.6之后多了appcompat_v7
    (转)android平台下使用点九PNG技术
    (转)多重背包
    (转)完全背包
    (转)01背包
    Longest Palindromic Substring
    Median of Two Sorted Arrays
  • 原文地址:https://www.cnblogs.com/mengff/p/13452704.html
Copyright © 2011-2022 走看看