丫是传说栍 發表於 2019-10-13 20:32:00

HTML5拖放排序

<p>最近在项目中遇到了拖动排序的需求,所以就学习了一下H5的新属性,写篇博客记录一下。</p>
<pre class="prettyprint"><span class="atn">draggable属性是指定当前元素可以被拖动的属性;我们要为需要拖动的元素设置该属性</span></pre>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="columns"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="column"</span><span style="color: rgba(255, 0, 0, 1)"> draggable</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">header</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>A<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">header</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="column"</span><span style="color: rgba(255, 0, 0, 1)"> draggable</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">header</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>B<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">header</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="column"</span><span style="color: rgba(255, 0, 0, 1)"> draggable</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">header</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>C<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">header</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 0, 1)">&lt;style&gt;
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> Prevent the text contents of draggable elements from being selectable. </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(128, 0, 0, 1)">
</span>{<span style="color: rgba(255, 0, 0, 1)">
-moz-user-select</span>:<span style="color: rgba(0, 0, 255, 1)"> none</span>;<span style="color: rgba(255, 0, 0, 1)">
-khtml-user-select</span>:<span style="color: rgba(0, 0, 255, 1)"> none</span>;<span style="color: rgba(255, 0, 0, 1)">
-webkit-user-select</span>:<span style="color: rgba(0, 0, 255, 1)"> none</span>;<span style="color: rgba(255, 0, 0, 1)">
user-select</span>:<span style="color: rgba(0, 0, 255, 1)"> none</span>;
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> Required to make elements draggable in old WebKit </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(255, 0, 0, 1)">
-khtml-user-drag</span>:<span style="color: rgba(0, 0, 255, 1)"> element</span>;<span style="color: rgba(255, 0, 0, 1)">
-webkit-user-drag</span>:<span style="color: rgba(0, 0, 255, 1)"> element</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.column </span>{<span style="color: rgba(255, 0, 0, 1)">
height</span>:<span style="color: rgba(0, 0, 255, 1)"> 150px</span>;<span style="color: rgba(255, 0, 0, 1)">
width</span>:<span style="color: rgba(0, 0, 255, 1)"> 150px</span>;<span style="color: rgba(255, 0, 0, 1)">
float</span>:<span style="color: rgba(0, 0, 255, 1)"> left</span>;<span style="color: rgba(255, 0, 0, 1)">
border</span>:<span style="color: rgba(0, 0, 255, 1)"> 2px solid #666666</span>;<span style="color: rgba(255, 0, 0, 1)">
background-color</span>:<span style="color: rgba(0, 0, 255, 1)"> #ccc</span>;<span style="color: rgba(255, 0, 0, 1)">
margin-right</span>:<span style="color: rgba(0, 0, 255, 1)"> 5px</span>;<span style="color: rgba(255, 0, 0, 1)">
-webkit-border-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-ms-border-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-moz-border-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
border-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-webkit-box-shadow</span>:<span style="color: rgba(0, 0, 255, 1)"> inset 0 0 3px #000</span>;<span style="color: rgba(255, 0, 0, 1)">
-ms-box-shadow</span>:<span style="color: rgba(0, 0, 255, 1)"> inset 0 0 3px #000</span>;<span style="color: rgba(255, 0, 0, 1)">
box-shadow</span>:<span style="color: rgba(0, 0, 255, 1)"> inset 0 0 3px #000</span>;<span style="color: rgba(255, 0, 0, 1)">
text-align</span>:<span style="color: rgba(0, 0, 255, 1)"> center</span>;<span style="color: rgba(255, 0, 0, 1)">
cursor</span>:<span style="color: rgba(0, 0, 255, 1)"> move</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.column header </span>{<span style="color: rgba(255, 0, 0, 1)">
color</span>:<span style="color: rgba(0, 0, 255, 1)"> #fff</span>;<span style="color: rgba(255, 0, 0, 1)">
text-shadow</span>:<span style="color: rgba(0, 0, 255, 1)"> #000 0 1px</span>;<span style="color: rgba(255, 0, 0, 1)">
box-shadow</span>:<span style="color: rgba(0, 0, 255, 1)"> 5px</span>;<span style="color: rgba(255, 0, 0, 1)">
padding</span>:<span style="color: rgba(0, 0, 255, 1)"> 5px</span>;<span style="color: rgba(255, 0, 0, 1)">
background</span>:<span style="color: rgba(0, 0, 255, 1)"> -moz-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21))</span>;<span style="color: rgba(255, 0, 0, 1)">
background</span>:<span style="color: rgba(0, 0, 255, 1)"> -webkit-gradient(linear, left top, right top,
                               color-stop(0, rgb(0,0,0)),
                               color-stop(0.50, rgb(79,79,79)),
                               color-stop(1, rgb(21,21,21)))</span>;<span style="color: rgba(255, 0, 0, 1)">
background</span>:<span style="color: rgba(0, 0, 255, 1)"> -webkit-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21))</span>;<span style="color: rgba(255, 0, 0, 1)">
background</span>:<span style="color: rgba(0, 0, 255, 1)"> -ms-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21))</span>;<span style="color: rgba(255, 0, 0, 1)">
border-bottom</span>:<span style="color: rgba(0, 0, 255, 1)"> 1px solid #ddd</span>;<span style="color: rgba(255, 0, 0, 1)">
-webkit-border-top-left-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-moz-border-radius-topleft</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-ms-border-radius-topleft</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
border-top-left-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-webkit-border-top-right-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-ms-border-top-right-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
-moz-border-radius-topright</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
border-top-right-radius</span>:<span style="color: rgba(0, 0, 255, 1)"> 10px</span>;
}<br><br>.ghost{<br>  optcity:0.6;<br>}</pre>
<pre><br><span style="color: rgba(128, 0, 0, 1)">
&lt;/style&gt;</span></pre>
</div>
<h2 id="toc-dragging-events">监听拖动事件</h2>
<ul>
<li><code>dragstart&nbsp; &nbsp;//当用户开始拖动一个元素或者一个选择文本的时候&nbsp;<code>dragstart</code>&nbsp;事件就会触发。</code></li>
<li><code>drag  &nbsp; &nbsp; //当元素或者选择的文本被拖动时触发&nbsp;<code>drag</code>&nbsp;事件 (每几百毫秒)</code></li>
<li><code>dragenter&nbsp; &nbsp;//当拖动的元素或被选择的文本进入有效的放置目标时,&nbsp;<code>dragenter</code>&nbsp;事件被触发。</code></li>
<li><code>dragleave&nbsp; &nbsp;//当一个被拖动的元素或者被选择的文本离开一个有效的拖放目标时,将会触发<code>dragleave</code>&nbsp;事件</code></li>
<li><code>dragover&nbsp; &nbsp; //当元素或者选择的文本被拖拽到一个有效的放置目标上时,触发&nbsp;<code>dragover&nbsp;</code>事件(每几百毫秒触发一次)。</code></li>
<li><code>drop&nbsp; &nbsp; &nbsp; &nbsp;//<code>当一个元素或是选中的文字被拖拽释放到一个有效的释放目标位置时,drop</code>&nbsp;事件被抛出。</code></li>
<li><code>dragend&nbsp; &nbsp; //拖放事件在拖放操作结束时触发(通过释放鼠标按钮或单击escape键)</code></li>
</ul>
<p>我们需要以下概念:源元素(拖动的起源点)、数据有效负载(我们尝试拖放的内容)和目标(接纳拖放内容的区域)。源元素可以是图片、列表、链接、文件对象、HTML 内容等。目标是接纳用户尝试放置的数据的放置区(或放置区组)。请注意,并非所有元素都可以作为目标(例如图片)。</p>
<h1><strong>dataTransfer</strong></h1>
<p>dataTransfer是用于元素拖动时控制拖动的类型和数据交换的,主要有以下属性:</p>
<ul>
<li>  dragEffect&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;获取 / 设置实际的放置效果,它应该始终设置成&nbsp;<code>effectAllowed</code>&nbsp; 的可能值之一;拖动时鼠标显示的效果,根据自己的功能来设定&nbsp;</li>
<li>
<ul>
<li><strong>copy</strong>:&nbsp;复制到新的位置</li>
<li><strong>move</strong>:&nbsp;移动到新的位置.</li>
<li><strong>link</strong>:&nbsp;建立一个源位置到新位置的链接.</li>
<li><strong>none</strong>:&nbsp;禁止放置(禁止任何操作).</li>
</ul>
</li>
<li>  effectAllowed&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;用来指定拖动时被允许的效果</li>
<li>
<p>可能的值:</p>
<ul>
<li><strong>copy</strong>:&nbsp;复制到新的位置.</li>
<li><strong>move</strong>:移动到新的位置 .</li>
<li><strong>link</strong>:建立一个源位置到新位置的链接.</li>
<li><strong>copyLink</strong>:&nbsp;允许复制或者链接.</li>
<li><strong>copyMove</strong>:&nbsp;允许复制或者移动.</li>
<li><strong>linkMove</strong>:&nbsp;允许链接或者移动.</li>
<li><strong>all</strong>:&nbsp;允许所有的操作.</li>
<li><strong>none</strong>:&nbsp;禁止所有操作.</li>
<li><strong>uninitialized</strong>:&nbsp;缺省值(默认值), 相当于 all.</li>
</ul>
</li>
<li>  files&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;包含一个在数据传输上所有可用的本地文件列表</li>
</ul>
<p>方法:</p>
<ul>
<li>clearData()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;删除与给定类型关联的数据。类型参数是可选的。如果类型为空或未指定,将删除所有类型相关联的数据。如果不存在指定类型的数据,或数据传输不包含任何数据,此方法将没有任何效果。</li>
<li>
<pre class="eval line-numbers language-html"><code class=" language-html">obj.clearData(type);</code></pre>
</li>
<li>getData()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;根据指定的类型检索数据,如果指定类型的数据不存在或者该&nbsp;<code>DataTransfer</code>&nbsp;对象中没有数据,方法将返回一个空字符串。</li>
<li>
<pre class="eval line-numbers language-html"><code class=" language-html">obj.getData(type);</code></pre>
</li>
<li>setData()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;为一个给定的类型设置数据。如果该数据类型不存在,它将添加到的末尾,这样类型列表中的最后一个项目将是新的格式。如果已经存在的数据类型,替换相同的位置的现有数据。就是,当更换相同类型的数据时,不会更改类型列表的顺序。</li>
<li>
<pre class="eval line-numbers language-html"><code class=" language-html">obj.setData(type,data);</code></pre>
</li>
<li>setDragImage()&nbsp; &nbsp;自定义一个期望的拖动时的图片。大多数情况下,这项不用设置,因为被拖动的节点被创建成默认图片。</li>
<li>
<pre class="eval line-numbers language-html"><code class=" language-html">obj.setDragImage(imgElement,offsetX,offsetY);    offsetX,offsetY为图片与鼠标的偏移量</code></pre>
</li>
</ul>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sortable(rootEl, onUpdate) {
    </span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> dragEl;
    </span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将所有的子类元素设置为可拖动的draggable = true</span>
    [].slice.call(rootEl.children).forEach(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (itemEl) {
      itemEl.draggable </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
    });
    </span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 该函数负责进行排序</span>
    <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> _onDragOver(evt) {
      evt.preventDefault();
      evt.dataTransfer.dropEffect </span>= 'move'<span style="color: rgba(0, 0, 0, 1)">;
      
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> target =<span style="color: rgba(0, 0, 0, 1)"> evt.target;
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (target &amp;&amp; target !== dragEl &amp;&amp; target.nodeName == 'LI'<span style="color: rgba(0, 0, 0, 1)">) {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Sorting</span>
            rootEl.insertBefore(dragEl, target.nextSibling ||<span style="color: rgba(0, 0, 0, 1)"> target);
      }
    }
    </span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 排序结束后的钩子函数</span>
    <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> _onDragEnd(evt){
      evt.preventDefault();
      
      dragEl.classList.remove(</span>'ghost'<span style="color: rgba(0, 0, 0, 1)">);
      rootEl.removeEventListener(</span>'dragover', _onDragOver, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
      rootEl.removeEventListener(</span>'dragend', _onDragEnd, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
</span>
<span style="color: rgba(0, 0, 0, 1)">      onUpdate(dragEl);
    }
    </span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 开始排序监听父元素的dragstart 事件</span>
    rootEl.addEventListener('dragstart', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (evt){
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 保存当前被拖动的子元素</span>
      dragEl = evt.target;
      
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置移动的类型</span>
      evt.dataTransfer.effectAllowed = 'move'<span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置要移动的数据</span>
      evt.dataTransfer.setData('Text'<span style="color: rgba(0, 0, 0, 1)">, dragEl.textContent);</span>
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 监听元素的dragover dragend 事件</span>
      rootEl.addEventListener('dragover', _onDragOver, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
      rootEl.addEventListener(</span>'dragend', _onDragEnd, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);

      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里如果不添加setTimeout拖出去的元素也会添加上该类名</span>
      setTimeout(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {</span>
            dragEl.classList.add('ghost'<span style="color: rgba(0, 0, 0, 1)">);
      }, </span>0<span style="color: rgba(0, 0, 0, 1)">)
    }, </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
}
                        
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Using                  </span>
sortable(document.getElementById('columns'), <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (item) {
    console.log(item);
});</span></pre>
</div>
<p>&nbsp;参考文章:1.Sorting with the help of HTML5 Drag'n'Drop API</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2.Native HTML5 Drag and Drop</p><br><br>
来源:https://www.cnblogs.com/recode-hyh/p/11668195.html
頁: [1]
查看完整版本: HTML5拖放排序