和谐自然 發表於 2021-10-20 10:50:00

HTML5拖拽技术介绍

<h1 id="html5-的拖拽实现">HTML5 的拖拽实现</h1>
<h3 id="前提draggable">前提:draggable</h3>
<p>将需要拖放的元素设置为 draggable = 'true'(img 和 a 元素默认为 true)</p>
<h2 id="一拖放相关事件">一、拖放相关事件</h2>
<h3 id="1-被拖动元素-ondragstartondragondragend">1. 被拖动元素: ondragstart、ondrag、ondragend</h3>
<ul>
<li><code>ondragstart</code> :用户开始拖动元素时触发</li>
<li><code>ondrag</code> :元素正在拖动时触发</li>
<li><code>ondragend</code> :用户完成元素拖动后触发</li>
</ul>
<h3 id="2-放置目标元素容器-ondragenterondragoverondragleaveondrop">2. 放置目标元素(容器): ondragenter、ondragover、ondragleave、ondrop</h3>
<ul>
<li><code>dragenter</code> :当被鼠标拖动的对象进入其容器范围内时触发此事件</li>
<li><code>dragover</code> :当某被拖动的对象在另一对象容器范围内拖动时触发此事件</li>
<li><code>dragleave</code> :当被鼠标拖动的对象离开其容器范围内时触发此事件</li>
<li><code>drop</code> :在一个拖动过程中,释放鼠标键时触发此事件。
<ul>
<li>源对象拖放到目标对象中,目标对象完全接受被拖拽对象时触发,可理解为在目标对象内松手时触发</li>
</ul>
</li>
</ul>
<p><strong>注意</strong>:对于 <code>dragover </code>和 <code>drop</code>,默认地,数据/元素无法被放置到其他元素中。为了实现拖放,我们必须阻止元素的这种默认的处理方式: 调用 <code>event.preventDefault(); </code></p>
<h2 id="二数据的传递datatransfer">二、数据的传递:dataTransfer</h2>
<p>所有拖放事件的参数 <code>DragEvent</code>中,都提供了一个数据传输对象: <code>dataTransfer</code>,用于在源对象和目标对象之间传递数据。</p>
<p><code>DataTransfer</code>对象包含了拖拽事件的状态,例如拖拽事件的类型(如拷贝 copy 或者移动 move),拖拽的数据(一个或者多个项)和每个拖拽项的类型(MIME 类型)。 <code>DataTransfer</code> 对象也有向拖拽数据中添加或删除项目的方法。</p>
<blockquote>
<p>参考链接:MDN : DataTransfer</p>
</blockquote>
<h3 id="1-datatransfer的方法">1. dataTransfer的方法</h3>
<h4 id="setdataformat-data">setData(format, data)</h4>
<p>该方法设置拖拽事件中要传递的数据,向 dataTransfer 中对象中存入数据。</p>
<p>接受两个参数:</p>
<p><code>format</code>:DOMString,表示要添加到 drag object的拖动数据的类型。例如text/plain、text/html、text/xml、text/uri-list<br>
<br><code>data</code>:DOMString,表示要添加到 drag object的数据。例如<code>event.dataTransfer.setData('text/plain', 'hello world')</code></p>
<p>注:如果给定类型的数据不存在,则将其添加到拖动数据存储的末尾,使得 dataTransfer.types 列表中的最后一个项目将是新类型。</p>
<h4 id="getdataformat">getData(format)</h4>
<p>该方法获得拖拽事件中传递的数据,从 <code>dataTransfer </code>对象中读取数据</p>
<p>参数 <code>format</code> 为在 setData 方法中指定的数据类型,例如: <code>event.dataTransfer.getData('text/plain')</code></p>
<h4 id="cleardata">clearData()</h4>
<p>该方法清空 <code>dataTransfer </code>对象中存储的数据,参数可选,为数据类型。若为空,则清空所有数据。</p>
<h4 id="setdragimageelement-x-y">setDragImage(element, x, y)</h4>
<p>该方法通过 img 元素来设置拖放图标</p>
<p><code>element</code> 表示拖拽时鼠标下面的图片(通常是 image 元素,也可以说 canvas 元素)<br><br>
<code>x</code>、<code>y</code>分别指示相对于图片的横向和纵向偏移量,相对应鼠标指针。</p>
<h3 id="2-datatransfer的属性">2. dataTransfer的属性</h3>
<h4 id="files-属性">files 属性</h4>
<p>返回被拖拽的文件列表,是一个 FileList 对象,有 length 属性,可通过下标访问。</p>
<p>如果拖动操作不涉及拖动文件,则此属性为空列表.</p>
<h4 id="dropeffect-属性">dropEffect 属性</h4>
<p>获取当前选定的拖放操作类型或者设置的为一个新的类型。值必须为 <code>none, copy, link 或 move</code> 。</p>
<p>必须在 <code>dragenter </code>事件处理函数中设置。</p>
<ul>
<li>none 不能把元素拖放至此(除文本框外全部元素的默认值)</li>
<li>move 移动到目标</li>
<li>copy 复制到目标</li>
<li>link 目标打开拖动元素(拖动元素必须是链接并有 URL)</li>
</ul>
<h4 id="dropeffect-属性-1">dropEffect 属性</h4>
<p>提供所有可用的操作类型。必须是 <code>none, copy, copyLink, copyMove, link, linkMove, move, all or uninitialized</code> 之一。</p>
<p>必须在 <code>dragstart </code>事件处理函数中设置。</p>
<ul>
<li>uninitialized 没有设置任何拖放行为</li>
<li>none 不能由任何行为</li>
<li>copy 仅允许 dropEffect 值为 copy</li>
<li>link 仅允许 dropEffect 值为 link</li>
<li>move 仅允许 dropEffect 值为 move</li>
<li>copyLink 允许 dropEffect 值为 copy 和 link</li>
<li>copyMove 允许 dropEffect 值为 copy 和 move</li>
<li>linkMove 允许 dropEffect 值为 link 和 move</li>
<li>all 允许任意 dropEffect</li>
</ul>
<h2 id="三示例html-拖拽示例-drag--drop">三、示例:HTML 拖拽示例 drag &amp; drop</h2>
<iframe height="500" style="width: 100%" scrolling="no" title="HTML拖拽示例drag &amp; drop" src="https://codepen.io/berryxu/embed/qBXNEww?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen &lt;a href="https://codepen.io/berryxu/pen/qBXNEww"&gt;
HTML拖拽示例drag &amp; drop&lt;/a&gt; by berryxu (&lt;a href="https://codepen.io/berryxu"&gt;@berryxu&lt;/a&gt;)
on &lt;a href="https://codepen.io"&gt;CodePen&lt;/a&gt;.
</iframe>
<p><strong>HTML 代码</strong></p>
<pre><code>&lt;div class="drag-item" id="dragitem" draggable="true"&gt;被拖动元素&lt;/div&gt;

&lt;div class="target-area"&gt;
&lt;div class="target" id="t1"&gt;目标元素&lt;/div&gt;
&lt;div class="target" id="t2"&gt;目标元素2&lt;/div&gt;
&lt;/div&gt;

&lt;div class="status-area"&gt;
&lt;div id="info"&gt;请拖动&lt;/div&gt;
&lt;div id="info2"&gt;&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p><strong>JavaScript 代码</strong></p>
<pre><code>let item = document.getElementById('dragitem')
let info = document.getElementById('info')
let info2 = document.getElementById('info2')
let targets = document.getElementsByClassName('target')

item.addEventListener('dragstart', function(ev){
ev.target.style.background = "lightgreen";
ev.target.style.color = "black";
ev.target.style.opacity = 0.5;
info.innerHTML = "开始拖动";

// 设定传递数据
ev.dataTransfer.setData('itemid', ev.target.id)
})

item.addEventListener('dragend', function(ev){
ev.target.style.background = "black";
ev.target.style.color = "white";
info.innerHTML = "结束拖动";
ev.target.style.opacity = 1;
info2.innerHTML = "";
})

item.addEventListener('drag', function(ev){
info2.innerHTML = "拖动中";
})

for(let target of targets) {

target.addEventListener('dragover', function(ev) {
    //默认地,数据/元素无法被放置到其他元素中。
    //为了实现拖放,我们必须阻止元素的这种默认的处理方式
    ev.preventDefault();
})

target.addEventListener('dragenter', function(ev) {
    ev.target.style.border = "3px dotted red";
})

target.addEventListener('dragleave', function(ev) {
    ev.target.style.border = "1px solid black";
})

target.addEventListener('drop', function(ev) {
    ev.preventDefault();
    let id = ev.dataTransfer.getData('itemid')
    ev.target.appendChild(document.getElementById(id))
})

target.addEventListener('dragover', function(ev) {
    ev.preventDefault();
    ev.target.style.border = "3px dotted red";
})
}
</code></pre><br><br>
来源:https://www.cnblogs.com/asahi-front/p/15427950.html
頁: [1]
查看完整版本: HTML5拖拽技术介绍