JavaScript實現元素拖動性能優化

前言:前幾天沒事幹寫了個小網站,打算用原生的javascript實現元素的拖動,可是事情並無想象的那麼順利,首先是實現了拖動的元素卡的不能再卡,簡直不可以,上圖~~javascript

GIF

看見沒?這就是效果,簡直讓人慾哭無淚啊,查了大量的資料也無濟於事,根本就沒有人會遇到過這個問題,可是通過N次試驗,終於找到了緣由——居然是我給這個元素添加了transition屬性致使的,元兇:java

image

去掉這個屬性以後,就變得徹底不同了chrome

GIF

 

至於緣由,我如今也不知道爲何,很無奈╮(╯▽╰)╭性能優化

接下來就是性能優化了,我原來的實現方式是給元素添加一個mousemove事件,而後判斷事件對象的buttons是否爲1,若是是1的話代表此時左鍵按下,而後記錄此時鼠標的x和y的座標,當下次觸發mousemove事件的時候用當前鼠標的位置減去上次記錄的鼠標的位置就是鼠標移動的距離,而後用元素當前的位置加上鼠標移動的距離就實現了拖動,代碼以下:性能

//實現拖動
        var lastClientX = 0;
        var lastClientY = 0;
        var count = 0;
        addCommandCard.addEventListener('mousemove', function() {
            if(arguments[0].buttons == 1) {
                addCommandCard.style.cursor = "default";
                arguments[0].preventDefault();
                if(count == 0) {
                    lastClientX = arguments[0].clientX;
                    lastClientY = arguments[0].clientY;
                    count++;
                } else {
                    addCommandCard.style.left = addCommandCard.offsetLeft + arguments[0].clientX - lastClientX + "px";
                    addCommandCard.style.top = addCommandCard.offsetTop + arguments[0].clientY - lastClientY + "px";
                    lastClientX = arguments[0].clientX;
                    lastClientY = arguments[0].clientY;
                    count++;
                }
            }
        });

今天看了個實現拖動的代碼,基本思路是,給元素添加mousedown事件,在這個事件處理程序中,首先記錄當前鼠標的位置與元素的offsetLeft和offsetTop的差值,而後給document添加mousemove和mouseup事件,在document的mousemove事件中,將元素的left設置爲當前鼠標X座標減去上面記錄的鼠標X座標和元素offsetLeft的差值,top值設置爲當前鼠標Y座標減去上面記錄的鼠標Y座標和元素offsetTop的差值,在mouseup事件中,設置document的mousemove和mouseup爲null,上面的話可能有些拗口,通俗點說就是首先記錄元素的左邊框和鼠標X座標的差值,而後記錄元素的上邊框和鼠標Y座標的差值,在鼠標移動的時候將元素的左邊框的值設置爲鼠標當前X座標的值減去鼠標和元素左邊框之間的相對距離,上邊框相似,由於在元素拖動的過程當中,鼠標和元素的相對位置始終沒有發生變化,因此只要用鼠標當前的位置減去鼠標和元素之間的相對距離就是元素拖動後的位置,代碼:測試

//實現拖動
        addCommandCard.addEventListener('mousedown', function() {
            arguments[0].preventDefault();
            var disX = arguments[0].clientX - addCommandCard.offsetLeft;
            var disY = arguments[0].clientY - addCommandCard.offsetTop;

            document.onmousemove = function() {
                addCommandCard.style.left = arguments[0].clientX - disX + 'px';
                addCommandCard.style.top = arguments[0].clientY - disY + 'px';
            }

            document.onmouseup = function() {
                document.onmousemove = null;
                document.onmouseup = null;
            }

        });

總結:在chrome中測試結果代表,兩種拖動方式均可以穩定在60fps,總得來講,差異不大,可是第一種有比較慢明顯的缺點,首先,第一種給元素添加了mousemove事件,那就意味着無論元素當前是否拖動,只要有鼠標移動到元素上,這個事件就不斷的觸發,雖然只有一條判斷語句,可是形成性能的白白浪費,而第二種是添加了mousedown事件,只有鼠標按下的時候纔會觸發,因此沒有這個問題,可是,若是在別處給document指定了mousemove和mouseup事件,那麼在元素拖動開始和結束以後,這些事件處理程序會變得無效,由於覆蓋的緣由,可是能夠經過DOM2級事件處理程序來解決,不算大問題優化

相關文章
相關標籤/搜索