ドラッグを徹底的に理解する-マウスイベントベースのドラッグとHTML 5 APIベースのドラッグを完全に実現

76603 ワード

一、マウスイベントに基づくドラッグ
原理——onmousedown、onmousemove、onmouseup
  • onmousedown
  • このイベントは、マウスボタンが押下すると
  • がトリガーされる.
  • このイベントをサポートするHTMLタグ:
  •    <a>, <address>, <area>, <b>, <bdo>, <big>, <blockquote>, <body>, <button>,
       <caption>, <cite>, <code>, <dd>, <dfn>, <div>, <dl>, <dt>, <em>, <fieldset>,  
       <form>, <h1> to <h6>, <hr>, <i>, <img>, <input>, <kbd>, <label>, <legend>,  
       <li>, <map>, <ol>, <p>, <pre>, <samp>, <select>, <small>, <span>, <strong>,  
       <sub>, <sup>, <table>, <tbody>, <td>, <textarea>, <tfoot>, <th>, <thead>,  
       <tr>, <tt>, <ul>, <var>
    
  • は、このイベントのJavaScriptオブジェクトをサポートします.button, document, link
  • onmousemove
  • このイベントは、マウスポインタの移動時に
  • をトリガーする.
  • このイベントをサポートするHTMLタグ:
  •    <a>, <address>, <area>, <b>, <bdo>, <big>, <blockquote>, <body>, <button>,  
       <caption>, <cite>, <code>, <dd>, <dfn>, <div>, <dl>, <dt>, <em>, <fieldset>,  
       <form>, <h1> to <h6>, <hr>, <i>, <img>, <input>, <kbd>, <label>, <legend>,  
       <li>, <map>, <ol>, <p>, <pre>, <samp>, <select>, <small>, <span>, <strong>,  
       <sub>, <sup>, <table>, <tbody>, <td>, <textarea>, <tfoot>, <th>, <thead>,  
       <tr>, <tt>, <ul>, <var>
    
  • は、このイベントのJavaScriptオブジェクトをサポートします.
    デフォルトでは、onmousemoveはマウスの移動が非常に頻繁であるため、オブジェクトのイベントではありません.
  • onmouseup
  • このイベントは、マウスボタンが離すと
  • がトリガーされる.
  • このイベントをサポートするHTMLタグ:
  •    <a>, <address>, <area>, <b>, <bdo>, <big>, <blockquote>, <body>, <button>,  
       <caption>, <cite>, <code>, <dd>, <dfn>, <div>, <dl>, <dt>, <em>, <fieldset>,  
       <form>, <h1> to <h6>, <hr>, <i>, <img>, <input>, <kbd>, <label>, <legend>,  
       <li>, <map>, <ol>, <p>, <pre>, <samp>, <select>, <small>, <span>, <strong>,  
       <sub>, <sup>, <table>, <tbody>, <td>, <textarea>, <tfoot>, <th>, <thead>,  
       <tr>, <tt>, <ul>, <var>
    
  • は、このイベントのJavaScriptオブジェクトをサポートします.button, document, link

  • 具体的な実装
    code:
    
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style>
            #test {
                width: 100px;
                height: 100px;
                background: #000;
                position: absolute;
                color: #fff;
            }
        style>
    head>
    
    <body>
        <div id="test">4616125div>
        <script>
            (function() {
                function Code() {}
                Code.prototype = {
                    addEvent: function() {
                        var that = this;
                        var oDiv = document.getElementById('test');
                        oDiv.onmousedown = function(ev) {
                            var ev = ev || event;
                            var distanceX = ev.clientX - this.offsetLeft;
                            var distanceY = ev.clientY - this.offsetTop;
                            if (oDiv.setCapture) {
                                oDiv.setCapture();
                            }
                            document.onmousemove = function(ev) {
                                var ev = ev || event;
                                oDiv.style.left = ev.clientX - distanceX + 'px';
                                oDiv.style.top = ev.clientY - distanceY + 'px';
                            };
                            document.onmouseup = function(ev) {
                                document.onmousemove = document.onmouseup = null;
                                if (oDiv.releaseCapture) {
                                    oDiv.releaseCapture();
                                }
                            };
                        };
                    },
    
                    init: function() {
                        var that = this;
                        window.onload = that.addEvent;
                    },
                }
                new Code().init();
            })();
        script>
    body>
    
    html>
    

    注意事項と問題点:
  • 注意事項
  • ドラッグされたdivのposition属性値はabsolute
  • に違いない.
  • onmousedownイベントはwindowに必要です.onload時負荷
  • ドラッグされたdivに文字が付いている場合は、変更div上のすべてのドラッグイベントをこのdivにバインドする必要があります.setCapture
  • を使用します.
  • onmousemoveとonmouseupはonmousedownに
  • をバインドする必要があります.
  • に存在する問題
  • は境界
  • から引きずり出される.
    ソリューション
  • は、ドラッグする要素の枠線距離の上下左右の画面間の距離をリアルタイムで計算するだけでよい.具体的なコードは以下の通りである:
  • code:
    
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            #oDiv {
                width: 100px;
                height: 100px;
                background-color: #000;
                position: absolute;
            }
        style>
    head>
    
    <body>
        55555555555
        <div id="oDiv">div>
        <script>
            oDiv.onmousedown = function(e) {
                var ev = e || event;
                var left = ev.clientX - oDiv.offsetLeft,
                    top = ev.clientY - oDiv.offsetTop;
                document.onmousemove = function(e) {
                    var ev = e || event;
                    var leftW = ev.clientX - left;
                    var topH = ev.clientY - top;
                    //      
                    if (leftW < 0) {
                        leftW = 0;
                    }
                    //      
                    if (topH < 0) {
                        topH = 0;
                    }
                    //      
                    if (leftW > document.documentElement.clientWidth - oDiv.offsetWidth) {
                        leftW = document.documentElement.clientWidth - oDiv.offsetWidth;
                    }
                    //      
                    if (topH > document.documentElement.clientHeight - oDiv.offsetHeight) {
                        topH = document.documentElement.clientHeight - oDiv.offsetHeight;
                    }
                    oDiv.style.left = leftW + 'px';
                    oDiv.style.top = topH + 'px';
                }
                document.onmouseup = function(e) {
                    document.onmousemove = null;
                    document.onmouseup = null;
                }
                return false;
            }
        script>
    body>
    
    html>
    

    result:
    これでマウスイベントのドラッグ&ドロップを使用して成功しました!
    二、HTML 5に基づくAPIのドラッグ&ドロップ
    前置き知識の紹介
    一般的なドラッグ操作は、ユーザーがマウスでドラッグ可能な要素を選択し、マウスを配置可能な要素に移動し、マウスを解放することです.操作中にイベントタイプがトリガーされ、dragやdragoverイベントタイプなど、複数回トリガーされるイベントタイプがあります.ここでは、いくつかの知識点について説明します.
  • 要素をドラッグします.
    ソースオブジェクトとも呼ばれ、マウスでクリックしてドラッグするオブジェクト(画像、div、文字など)を指します.
  • 要素を配置できます.
    ターゲットオブジェクトとも呼ばれ、ソースオブジェクトを配置できる領域を指します
  • イベント:
  • Event
    On Event Handler
    Description
    drag
    ondrag
    エレメントまたは選択したテキストをドラッグするとトリガーされます
    dragend
    ondragend
    ドラッグ操作が終了するとトリガーされます(マウスボタンを離すかEscキーを押すなど)
    dragenter
    ondragenter
    エレメントまたは選択したテキストを解放可能なターゲットにドラッグするとトリガーされます.
    dragexit
    ondragexit
    要素がドラッグ操作で選択されていない場合にトリガーされます
    dragleave
    ondragleave
    要素または選択したテキストをドラッグして解放可能なターゲットから離れるとトリガーされます.
    dragover
    ondragover
    エレメントまたは選択したテキストが解放可能ターゲットにドラッグされるとトリガーされます.
    dragstart
    ondragstart
    ユーザーがエレメントまたは選択したテキストのドラッグを開始するとトリガーされます.
    drop
    ondrop
    エレメントまたは選択したテキストが解放可能ターゲットで解放されるとトリガーされます.
    ps:オペレーティングシステムからブラウザにファイルをドラッグするとdragstartおよびdragendイベントはトリガーされません
  • インタフェース:
  • HTML 5は、すべてのドラッグ関連イベントに新しい属性を提供します.
  • ソースオブジェクトとターゲットオブジェクトのイベント間転送データev.dataTransfer {}//
  • ソースオブジェクト上のイベント処理でデータを保存します.ev.dataTransfer.setData(key,value);//key,value
  • ターゲットオブジェクト上のイベント処理でデータを読み出す:var value2 = ev.dataTransfer.getData(key);
  • 互換性
  • ps:画像ソース(CAN I USE?)
    実装コード
    code:
    
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style type="text/css">
            #thatDiv {
                width: 500px;
                height: 100px;
                border: 1px solid red;
                position: relative;
            }
            #thisDiv {
                width: 500px;
                height: 100px;
                border: 1px solid black;
                margin-bottom: 20px;
            }
            #tarDiv,
            #tarDiv1,
            #tarDiv2,
            #tarDiv3,
            #tarDiv4 {
                float: left;
                width: 50px;
                height: 50px;
                background-color: #000;
                border: 1px #fff solid;
            }
            .tarDiv {
                color: #fff;
                text-align: center;
                line-height: 50px;
            }
        style>
    head>
    
    <body>
        <div id="thisDiv">
            <div id="tarDiv" class="tarDiv" draggable="true">1div>
            <div id="tarDiv1" class="tarDiv" draggable="true">2div>
            <div id="tarDiv2" class="tarDiv" draggable="true">3div>
            <div id="tarDiv3" class="tarDiv" draggable="true">4div>
            <div id="tarDiv4" class="tarDiv" draggable="true">5div>
        div>
        <div id="thatDiv">div>
    
        <script type="text/javascript">
            var tarDiv = document.getElementsByClassName("tarDiv");
            var thisDiv = document.getElementById("thisDiv");
            var thatDiv = document.getElementById("thatDiv");
            thisDiv.ondragstart = function(ev) {
                var ev = ev || window.event;
                ev.dataTransfer.setData("text", ev.target.id); //        id  dataTransfer   
                window.thisId = ev.target.id;
                ev.dataTransfer.effectAllowed = "copy";
            }
            thatDiv.ondragover = function(ev) { //  dragover     
                var ev = ev || window.event;
                if (typeof ev.preventDefault == "function") {
                    ev.preventDefault();
                } else {
                    ev.returnValue = false;
                }
                var div = document.getElementById(window.thisId);
                thatDiv.appendChild(div);
                div.style.cssText = "border:1px #fff dashed;";
    
                ev.preventDefault();
                ev.dataTransfer.dropEffect = "copy";
            }
            thatDiv.ondragenter = function(ev) { //  dragenter     
                var ev = ev || window.event;
                if (typeof ev.preventDefault == "function") {
                    ev.preventDefault();
                } else {
                    ev.returnValue = false;
                }
            }
            thatDiv.ondragleave = function(ev) {
                var ev = ev || window.event;
                var removeDiv = document.getElementById(window.thisId);
                thatDiv.removeChild(removeDiv);
                thisDiv.appendChild(removeDiv);
                removeDiv.style.cssText = "border:1px #fff solid;";
                ev.preventDefault();
            }
            thatDiv.ondrop = function(ev) {
                var ev = ev || window.event;
                var divId = ev.dataTransfer.getData("Text"); // dataTransfer       
                if (typeof ev.preventDefault == "function") { //  drop       
                    ev.preventDefault();
                } else {
                    ev.returnValue = false;
                }
                var moveDiv = document.getElementById(divId);
                thatDiv.appendChild(moveDiv);
                moveDiv.setAttribute('draggable', 'false');
                moveDiv.style.cssText = "border:1px #fff solid;";
    
            }
        script>
    body>
    
    html>
    

    result:
    参考資料
  • w 3 schoolオンラインチュートリアル
  • 新しいブログアドレス:http://www.caomage.com