HTML5之拖拽(兼容IE和非IE)

前世:項目中須要拖動div,而後和某個div進行位置交換,這不是關鍵,關鍵是還要保存位置,而後在下次打開的時候按照保存的位置顯示。還好本人功力深厚,一會兒就想到了用localStorage來保存,事實證實真的很好用哦。保存數據的方法有了,而後開始"探索"如何用html(5)和js來實現拖拽的效果,因爲H5給了比較規範的實現方式,因此在Chrome中輕鬆實現,萬惡的IE(不多罵IE)居然不兼容,NONONONO,心塞,只好用了兩種方式分別實現拖拽效果。(其實兩種方式內的代碼很類似,惟一不一樣的就是事件的名稱罷了,方法體幾乎如出一轍)。javascript

今世:html

先來段HTML代碼吧.java

<body onload="init()">
    <div id="content"></div>

    <div class="dragDiv" id="div1">
        <img id="drag1" src="1.jpg" width="336" index="1" height="69" draggable="true" />
    </div>
    <br>
    <div class="dragDiv" id="div2">
        <img id="drag2" src="2.jpg" width="236" index="2" height="49" draggable="true" />
    </div>
    <div class="dragDiv" id="div3">
        <img id="drag3" src="big.png" width="336" index="3" height="69" draggable="true" />
    </div>
    <br>
    <div class="dragDiv" id="div4">
        <img id="drag4" src="mvp1.jpg" width="236" index="4" height="49" draggable="true" />
    </div>
</body>

 代碼爲整個HTML代碼片斷,沒有特別的地方,惟一須要注意的就是draggable屬性,設置爲true,這樣就能夠拖動他了。而後,給每一個img(能夠換成本身須要的element標籤)添加了一個自定義屬性index,用於在交   換位置以後,保存元素的順序。數組

Javascript代碼:app

 function init() {

            var data;
            $(".dragDiv").each(function () {

                //若是是IE
                if (!!window.ActiveXObject || "ActiveXObject" in window) {

                 
                  
                    $(this).on("dragstart", function (ev) {
                        /*拖拽開始*/
                        //拖拽效果
                        ev.originalEvent.dataTransfer.effectAllowed = "move";
                      
                        data = ev.target.id;
                        return true;
                    });

                    $(this).on("dragend", function (ev) {
                        return false
                    });

                    $(this).on("dragover", function (ev) {
                        /*拖拽元素在目標元素頭上移動的時候*/
                        ev.preventDefault();
                        return true;
                    });

                    $(this).on("dragenter", function (ev) {

                        return true;
                    });

                    $(this).on("drop", function (ev) {
                        ev.preventDefault();
                        var src = document.getElementById(data);

                        var srcParent = src.parentNode;
                        var tgt = ev.currentTarget.firstElementChild;

                        //用src替換tgt
                        ev.currentTarget.replaceChild(src, tgt);
                        srcParent.appendChild(tgt);

                        var sourceIndex = $(src).attr("index");
                        var targetIndex = $(tgt).attr("index");

                        //存在保存的索引值
                        if (localStorage.indexs) {
                            var indexs = localStorage.indexs;
                            indexs = indexs.replace(sourceIndex, "*");
                            indexs = indexs.replace(targetIndex, "&");
                            indexs = indexs.replace("*", targetIndex);
                            indexs = indexs.replace("&", sourceIndex);
                            //將新的索引順序保存在localStorage
                            localStorage.indexs = indexs;
                        }
                    });

                }
                    //Html5的拖拽IE不支持
                else {

                  
                    $(this).on("dragover", function (event) {
                       event.preventDefault();
                    });
                    $(this).on("drop", function (ev) {

                        ev.preventDefault();
                        var src = document.getElementById(ev.originalEvent.dataTransfer.getData("src"));

                        var srcParent = src.parentNode;
                        var tgt = ev.currentTarget.firstElementChild;

                        //用src替換tgt
                        ev.currentTarget.replaceChild(src, tgt);
                        srcParent.appendChild(tgt);

                        var sourceIndex = $(src).attr("index");
                        var targetIndex = $(tgt).attr("index");

                        //存在保存的索引值
                        if (localStorage.indexs) {
                            var indexs = localStorage.indexs;
                            indexs = indexs.replace(sourceIndex, "*");
                            indexs = indexs.replace(targetIndex, "&");
                            indexs = indexs.replace("*", targetIndex);
                            indexs = indexs.replace("&", sourceIndex);
                            //將新的索引順序保存在localStorage
                            localStorage.indexs = indexs;
                        }
                    });


                    $(this).children(0).on("dragstart", function (event) {
                        event.originalEvent.dataTransfer.setData("src", event.target.id);
                    });
                }
            });

            //不存在保存的索引值,則保存初始化
            if (!localStorage.indexs) {
                localStorage.indexs = "1,2,3,4";
            }
            else {
                //從保存的索引值中,按照順序顯示div
                var indexs = localStorage.indexs.toString().split(",");
                for (var i = 0; i < indexs.length; i++) {
                    var index = indexs[i];
                    var divElement = document.getElementById("div" + index);
                    document.getElementById("content").insertAdjacentElement("beforeend", divElement);
                }
            }
        }

 上述代碼好長,嚇死人了,不要緊,慢慢分析。代碼分爲兩部分,分別是處理IE和非IE的邏輯,咱們主要分析非IE的邏輯(由於通用)。一共有三個主要的事件:
ondragstart:開始拖拽,當在某一個可拖拽的Element上按下鼠標拖動就觸發此事件。
  在此方法中將用於拖拽(交換位置)的Element的Id經過setData保存起來,在dorp事件中會使用到此數據。
ondragover:當拖拽的動做,移動到目標Element。
  此方法只有一行代碼,event.preventDefault(),意思是阻止元素髮生默認的行爲,也就是不要顯示元素默認的拖拽鼠標懸浮效果。
ondrop:當拖放結束,鬆開鼠標,觸發此事件。
  這個方法代碼略多,主要作了幾件事情。
  1.經過getdata獲得保存的數據,而後找到拖拽的元素Element,而後再獲得目標Element,用於交換;
      2.經過replaceChild方法將Source Element和Target Element進行替換操做,而後將Target從新添加到Source Element的父容器中(經過appendChild方法);
  3.在上文的HTML中看到給每個可拖動的img添加了index屬性,那麼就須要獲得Source Element和Target Element的index,用於保存到localStorage中;
  4.在獲得兩個Index以後,就須要從localStorage中取出以前保存的indexs值,而後分別替換Source Index和Target Index爲一個特殊字符(你也能夠替換爲任意的符號,主要是爲了能夠比較簡單的進行替換);
  5.在最後一步,咱們用Source Index替換Target Index的特殊字符,用Target Index替換Source Index的特殊字符,而後將新的indexs值保存在localStorage中,這樣咱們的拖動並保存已經完成了;this

在IE中的處理,和H5的標準方式基本一致,惟一區別就是對setData 的訪問,和對dataTransfer的訪問,在上文中因爲setData一直出錯,索性就放棄了,直接使用了一個局部變量,對dataTransfer的訪問也給出了正確的使用方式,另外就是Ie對拖拽行爲的事件名稱和H5標準的事件名稱有一些區別,方法體基本一致。spa

還沒結束,哈哈哈。咱們只作了保存,但是加載呢,沒錯保存是其次,從新加載顯示正確的順序纔是最主要的。
在init方法體中咱們先判斷是否已經存在了localStorage.indexs,若是不存在,說明咱們沒有保存過,那麼就給他一個默認值吧(其實也能夠不給它,反正拖拽後仍是要保存的額),若是存在則取出indexs,而後拆分紅一個數組,最後遍歷整個數組,找到索引對應的div(能夠是任意一個元素,不必定是div),而後放入目標div父容器中便可。htm

 

好了,這個功能在Chrome中實現起來挺簡單的,就是一些標準的事件,而後進行數據傳遞,保存,加載便可。在IE中真是夠了,各類不兼容,各類出錯,還好最後也是給弄出來了。但願能幫助到你們。blog

相關文章
相關標籤/搜索