angular项目中输入延迟以及拖拽卡顿

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了angular项目中输入延迟以及拖拽卡顿相关的知识,希望对你有一定的参考价值。

参考技术A 之前有一个angular项目,页面上表单不算多,也就一百来个(这个不固定,有的地方多,有的地方少),但是再输入的时候会造成输入延迟,反应不灵敏,对用户体验极其不好。还有一个功能就是拖拽功能(原生,没有使用官方中的拖拽功能),从左边拖到右边区域,拖拽区域少的时候还挺流畅,但一旦有几百上千的时候反应极其的慢,佛系的人都要变暴躁。

上面两个问题其实都和angular的机制有关。一个双向绑定一个拖拽归根结底都是因为 angular 的变化检测
angular的双向绑定主要是脏数据检查,如果大量的检查,效率比较低。(双向绑定时向zone挂载一个异步函数,对数据改变是做处理,及时将变化反馈显示在页面上)可能就会输入延迟
拖拽(也是向zone挂载异步函数)则是因为angular对每个可移动像素的元素进行检测而且还可能涉及对dom的操作,当拖拽区域数量较为多时,绑定的函数就越多,angular需要检测的元素区域就越来越多,处理起来就越力不从心(即使元素隐藏也不代表不会进行变化检测)

对频繁的操作(如dragover)不去触发变更检测。使用 NgZone 中的 runOutsideAngular 方法,angular不会对里面的变化进行跟踪。

我对angular的变化检测也似懂非懂 -_-

vue左右拖拽,内置iframe拖拽卡顿问题

如图:实现左侧是 iframe的 pdf预览器,右侧是输入文字,问问题。中间可以调节2侧宽度

<div class="box" ref="box">
        <div class="left">
            <!--左侧div内容-->
        </div>
        <div class="resize" title="收缩侧边栏" @mousedown="changeIframeDivStyle('')" @onmouseup="changeIframeDivStyle('none')" ></div>
        <div class="mid">
          <!--在此处添加遮罩层-->
            <div class="iframeDiv"></div>
            <!--右侧div内容-->
            <iframe></iframe>
        </div>
    </div>
 /* 这块是重点 */
.iframeDiv 
        width: 100%;
        height: 100%;
        position: absolute;
        z-index: 1111;
        filter: alpha(opacity=0);
        opacity: 0;
        background: transparent;
        margin-top: 30px;
        /*display: none;*/
    
 /* 拖拽相关样式 */
    /*包围div样式*/
    .box 
        width: 100%;
        height: 100%;
        margin: 1% 0px;
        overflow: hidden;
        box-shadow: -1px 9px 10px 3px rgba(0, 0, 0, 0.11);
    
    /*左侧div样式*/
    .left 
        width: calc(32% - 10px);  /*左侧初始化宽度*/   
        height: 100%;
        background: #FFFFFF;
        float: left;
    
    /*拖拽区div样式*/
    .resize 
        cursor: col-resize;
        float: left;
        position: relative;
        top: 45%;
        background-color: #d6d6d6;
        border-radius: 5px;
        margin-top: -10px;
        width: 10px;
        height: 50px;
        background-size: cover;
        background-position: center;
        /*z-index: 99999;*/
        font-size: 32px;
        color: white;
    
    /*拖拽区鼠标悬停样式*/
    .resize:hover 
        color: #444444;
    
    /*右侧div'样式*/
    .mid 
        float: left;
        width: 68%;   /*右侧初始化宽度*/
        height: 100%;
        background: #fff;
        box-shadow: -1px 4px 5px 3px rgba(0, 0, 0, 0.11);
    
dragControllerDiv: function () 
                var resize = document.getElementsByClassName('resize');
                var left = document.getElementsByClassName('left');
                var mid = document.getElementsByClassName('mid');
                var box = document.getElementsByClassName('box');
                for (let i = 0; i < resize.length; i++) 
                    // 鼠标按下事件
                    resize[i].onmousedown = function (e) 
                        //颜色改变提醒
                        resize[i].style.background = '#818181';
                        var startX = e.clientX;
                        resize[i].left = resize[i].offsetLeft;
                        // 鼠标拖动事件
                        document.onmousemove = function (e) 
                            var endX = e.clientX;
                            var moveLen = resize[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
                            var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度

                            if (moveLen < 32) moveLen = 32; // 左边区域的最小宽度为32px
                            if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px

                            resize[i].style.left = moveLen; // 设置左侧区域的宽度

                            for (let j = 0; j < left.length; j++) 
                                left[j].style.width = moveLen + 'px';
                                mid[j].style.width = (box[i].clientWidth - moveLen - 10) + 'px';
                            
                        ;
                        // 鼠标松开事件
                        document.onmouseup = function (evt) 
                        //隐藏遮罩div
                        var iframeDiv = document.getElementsByClassName("iframeDiv");
            iframeDiv[0].style.display = "none";
                            //颜色恢复
                            resize[i].style.background = '#d6d6d6';
                            document.onmousemove = null;
                            document.onmouseup = null;
                            resize[i].releaseCapture && resize[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
                        ;
                        resize[i].setCapture && resize[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
                        return false;
                    ;
                
            ,
changeIframeDivStyle(display) 
                var iframeDiv = document.getElementsByClassName('iframeDiv');
                iframeDiv[0].style.display = display;
            ,
// mounted 调用
this.dragControllerDiv();

转载自:https://blog.csdn.net/qian_li_hui/article/details/127410905

以上是关于angular项目中输入延迟以及拖拽卡顿的主要内容,如果未能解决你的问题,请参考以下文章

“未捕获的类型错误:无法在 Websocket Angular JS 上读取未定义的属性‘延迟’”

Angular 项目中的 Blazor webassembly

VS Code 编辑文件延迟大,卡顿的解决办法

Angular管道PIPE介绍

一个拖拽卡顿问题引发出对setTimeOut的探索

直播平台性能测试技术