Maison  >  Article  >  interface Web  >  Parlez d'une compréhension approfondie du glisser-déposer natif JavaScript

Parlez d'une compréhension approfondie du glisser-déposer natif JavaScript

高洛峰
高洛峰original
2017-01-18 13:31:351053parcourir

Les mots précédents

Le glisser-déposer (DnD) est en fait deux actions : le glisser-déposer. Cela implique donc deux éléments. L'un est l'élément glissé, appelé source du glisser-déposer ; l'autre est la cible à déposer, appelée cible du glisser-déposer. Cet article présentera en détail le glisser-déposer natif en divisant ces deux concepts

source du glisser-déposer

Quel type d'élément est la source du glisser-déposer ?

HTML5 spécifie un attribut déplaçable pour tous les éléments HTML, indiquant si l'élément peut être glissé

L'attribut déplaçable des images et des liens est automatiquement défini sur true, tandis que les autres La valeur par défaut de cet attribut de l'élément est false

[Note] Draggable='true' doit être défini pour prendre effet, seul le paramètre draggable ne fonctionnera pas

Par défaut, le texte ne peut être déplacé que lorsqu'il est sélectionné, tandis que les images et les liens peuvent être déplacés à tout moment. Les autres éléments ne peuvent pas être glissés et déposés

<input value="文字可拖动">
<img alt="图像可拖动" src="http://files.cnblogs.com/files/xiaohuochai/zan.gif">
<a href="#">链接可拖动</a>
<div id="test" style="height:30px;width:300px;background:pink;">元素不可拖动</div>

Lorsque l'attribut draggable est défini pour l'élément, les éléments ordinaires peuvent également être glissés

<div draggable="true" style="height:30px;width:100px;background:pink;"></div>

Compatible

Le navigateur IE9 ne prend pas en charge l'attribut draggable, mais la méthode dragDrop() peut être appelée via le gestionnaire d'événements mousedown pour obtenir l'effet glisser

<div id="test" style="height:30px;width:300px;background:pink;"></div>
<script>
test.onmousedown = function(){
this.dragDrop();
}
</script>

 [Note] Si vous souhaitez que Firefox prenne en charge l'attribut draggable, vous devez ajouter un gestionnaire d'événement ondragstart et utiliser la méthode setData() sur l'objet dataTransfer pour démarrer l'effet

Événement glisser-déposer

La source glisser-déposer implique 3 événements glisser-déposer. Lors du glisser-déposer de la source, les trois événements de dragstart, drag et dragend sont déclenchés en séquence

dragstart

Lorsque le bouton de la souris est enfoncé et que la souris commence à être déplacé, l'événement dragstart est déclenché sur l'élément glissé-déposé. À ce moment, le curseur se transforme en symbole « impossible de placer » (il y a une barre oblique inverse dans le cercle), indiquant que l'élément ne peut pas être placé sur lui-même

glisser

Déclencher le dragstart Après l'événement, l'événement glisser sera déclenché immédiatement, et cet événement continuera à être déclenché pendant que l'élément est déplacé

dragend

Lorsque le glissement s'arrête (que l'élément soit déplacé) qu'il soit placé sur une cible de placement valide ou une cible de placement invalide), l'événement dragend

<div id="test" draggable="true" style="height:30px;width:100px;background:pink;">0</div>
<script>
var timer,i=0;
test.ondragstart = function(){
this.style.backgroundColor = &#39;lightgreen&#39;;
}
test.ondrag = function(){
if(timer) return;
timer = setInterval(function(){
test.innerHTML = i++;
},100)
}
test.ondragend = function(){
clearInterval(timer);
timer = 0;
this.style.backgroundColor = &#39;pink&#39;;
}
</script>

sera déclenché

Cible du glisser-déposer

La cible du glisser-déposer fait référence à la cible où est placé l'élément glissé lorsque la souris est relâchée

Lorsque la source du glisser-déposer est glissée vers la cible du glisser-déposer, dragenter et dragover seront déclenchés en séquence et les quatre événements dragleave ou drop

dragenter

.

Tant qu'un élément est glissé vers la cible du dépôt, l'événement dragenter

est déclenché par dragover

Lorsque l'élément glissé se déplace dans la plage du dépôt target, l'événement dragover continue d'être déclenché

dragleave

Si l'élément est Faites glisser la cible de dépôt, déclenchez l'événement dragleave

drop

Si l'élément est déposé dans la cible de dépôt, déclenchez l'événement drop

 [ Remarque] Le comportement par défaut de l'événement drop de Firefox est d'ouvrir l'URL placée sur la cible de largage. Pour que Firefox prenne en charge le glisser-déposer normal, le comportement par défaut de l'événement drop doit être annulé

Par défaut, l'élément cible n'est pas autorisé à être placé, donc l'événement drop ne se produira pas . Tant que le comportement par défaut est bloqué dans les événements dragover et dragenter, il peut devenir une cible de dépôt autorisée et permettre aux événements de dépôt de se produire. À ce stade, le curseur se transforme en un symbole qui permet le placement

<div id="test" draggable="true" style="height:30px;width:130px;background:pink;float:left;">拖放源</div>
<div id="target" style="float:right;height: 200px;width:200px;background:lightblue;">拖放目标</div>
<script>
var timer,i=0;
var timer1,i1=0;
//兼容IE8-浏览器
test.onmousedown = function(){
if(this.dragDrop){
this.dragDrop();
}
}
test.ondragstart = function(){
this.style.backgroundColor = &#39;lightgreen&#39;;
this.innerHTML = &#39;开始拖动&#39;;
}
test.ondrag = function(){
if(timer) return;
timer = setInterval(function(){
test.innerHTML = &#39;元素已被拖动&#39; + ++i + &#39;秒&#39;;
},1000);
}
test.ondragend = function(){
clearInterval(timer);
timer = 0;i =0;
this.innerHTML = &#39;结束拖动&#39;;
this.style.backgroundColor = &#39;pink&#39;;
}
target.ondragenter = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
this.innerHTML = &#39;有元素进入目标区域&#39;;
this.style.background = &#39;red&#39;;
}
target.ondragover = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
if(timer1) return;
timer1 = setInterval(function(){
target.innerHTML = &#39;元素已进入&#39; + (++i1) + &#39;秒&#39;;
},1000);
}
target.ondragleave = function(){
clearInterval(timer1);
timer1 = 0;i1=0;
this.innerHTML = &#39;元素已离开目标区域&#39;;
this.style.backgroundColor = &#39;lightblue&#39;;
}
target.ondrop = function(){
clearInterval(timer1);
timer1 = 0;i1=0;
this.innerHTML = &#39;元素已落在目标区域&#39;;
this.style.backgroundColor = &#39;orange&#39;;
}
</script>

objet dataTransfer

Afin d'implémenter le glisser et opérations de dépôt L'échange de données introduit l'objet dataTransfer, qui est un attribut de l'objet événement et est utilisé pour transférer des données au format chaîne de l'élément glissé vers la cible de placement

L'objet dataTransfer a deux principaux méthodes : getData () et setData()

 getData() peuvent obtenir la valeur enregistrée par setData(). Le premier paramètre de la méthode setData(), qui est également le seul paramètre de la méthode getData(), est une chaîne indiquant le type de données enregistrées. La valeur est "text" ou "URL"

IE ne définit que deux types de données valides : "texte" et "URL", tandis que HTML5 l'étend pour permettre de spécifier différents types MIME. Compte tenu de la compatibilité ascendante, HTML5 prend également en charge "text" et "URL", mais ces deux types seront mappés à "text/plain" et "text/uri-list"


En fait, le L'objet dataTransfer peut enregistrer une valeur pour chaque type MIME. En d'autres termes, il n'y aura aucun problème pour enregistrer un morceau de texte et une URL dans cet objet en même temps


 [Note] Les données enregistrées dans l'objet dataTransfer ne peuvent être lues que dans le drop gestionnaire d'événements


Lorsque vous faites glisser le texte dans la zone de texte, le navigateur appellera la méthode setData() pour enregistrer le texte glissé dans l'objet dataTransfer au format "texte". De même, lors du glisser-déposer d'un lien ou d'une image, la méthode setData() est appelée et l'URL est enregistrée. Ensuite, lorsque ces éléments sont glissés et déposés dans la cible de dépôt, les données peuvent être lues via getData()

<div>请将从这堆内容不同乱七八糟的文字中挑选一些移动到拖放目标中</div>
<div id="target" style="margin-top:20px;height: 100px;width:200px;background:lightblue;">拖放目标</div>
<div id="result"></div>
<script>
target.ondragenter = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
this.innerHTML = &#39;有元素进入目标区域&#39;;
this.style.background = &#39;red&#39;;
}
target.ondragover = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
}
target.ondragleave = function(e){
e = e || event;
this.innerHTML = &#39;元素已离开目标区域&#39;;
this.style.backgroundColor = &#39;lightblue&#39;;
}
target.ondrop = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
result.innerHTML = &#39;落入目标区域的文字为:&#39; + e.dataTransfer.getData(&#39;text&#39;);
this.innerHTML = &#39;元素已落在目标区域&#39;;
this.style.backgroundColor = &#39;orange&#39;;
}
</script>

Bien sûr, vous pouvez également utilisez dragstart Appelez setData() dans le gestionnaire d'événements pour enregistrer manuellement les données que vous souhaitez transmettre pour une utilisation ultérieure

<div id="test" draggable="true" data-value="这是一个秘密" style="height:30px;width:100px;background:pink;">拖动源</div>
<div id="target" style="margin-top:20px;height: 100px;width:200px;background:lightblue;">拖放目标</div>
<div id="result"></div>
<script>
//兼容IE8-浏览器
test.onmousedown = function(){
if(this.dragDrop){
this.dragDrop();
}
}
test.ondragstart = function(e){
e = e || event;
e.dataTransfer.setData(&#39;text&#39;,test.getAttribute(&#39;data-value&#39;));
}
target.ondragenter = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
this.innerHTML = &#39;有元素进入目标区域&#39;;
this.style.background = &#39;red&#39;;
}
target.ondragover = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
}
target.ondragleave = function(e){
e = e || event;
this.innerHTML = &#39;元素已离开目标区域&#39;;
this.style.backgroundColor = &#39;lightblue&#39;;
}
target.ondrop = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
result.innerHTML = &#39;落入目标区域的文字为:&#39; + e.dataTransfer.getData(&#39;text&#39;);
this.innerHTML = &#39;元素已落在目标区域&#39;;
this.style.backgroundColor = &#39;orange&#39;;
}
</script>
   
改变光标
  利用dataTransfer对象,不仅可以传输数据,还能通过它来确定被拖动的元素以及作为放罝目标的元素能够接收什么操作。为此,需要访问dataTransfer对象的两个属性:dropEffect和effectAllowed
  实际上,这两个属性并没有什么用,只是拖动源在拖动目标上移动时,改变不同的光标而已(但是,有一种情况除外)
dropEffect
  dropEffect属性可以知道被拖动的元素能够执行哪种放置行为。这个属性有下列4个可能的值
  "none":不能把拖动的元素放在这里。这是除文本框之外所有元素的默认值(此时,将无法触发drop事件)
  "move":应该把拖动的元素移动到放置目标
  "copy":应该把拖动的元素复制到放置目标
  "link":表示放置目标会打开拖动的元素(但拖动的元素必须是一个链接,有URL)
  在把元素拖动到放置目标上时,以上每一个值都会导致光标显示为不同的符号
  [注意]必须在ondragover事件处理程序中针对放置目标来设置dropEffect属性
effectAllowed
  dropEffect属性只有搭配effectAllowed属性才有用。effectAllowed属性表示允许拖动元素的哪种dropEffect
  effectAllowed属性可能的值如下
  "uninitialized":没有给被拖动的元素设置任何放置行为
  "none":被拖动的元素不能有任何行为 
 "copy":只允许值为"copy"的dropEffect
  "link"只允许值为"link"的dropEffect
  "move":只允许值为"move"的dropEffect
  "copyLink":允许值为"copy"和"link"的dropEffect
  "copyMove":允许值为"copy"和"move"的dropEffect
  "linkMove":允许值为"link"和"move"的dropEffect
 "all":允许任意dropEffect
  [注意]必须在ondragstart事件处理程序中设置effectAllowed属性
<div id="test" draggable="true" style="height:30px;width:100px;background:pink;display:inline-block;">拖放源</div>
<br>
<div id="target1" style="margin-top:20px;height: 100px;width:150px;background:lightblue;display:inline-block;">(none)拖放目标</div>
<div id="target2" style="margin-top:20px;height: 100px;width:150px;background:lightblue;display:inline-block;">(move)拖放目标</div>
<div id="target3" style="margin-top:20px;height: 100px;width:150px;background:lightblue;display:inline-block;">(copy)拖放目标</div>
<div id="target4" style="margin-top:20px;height: 100px;width:150px;background:lightblue;display:inline-block;">(link)拖放目标</div>
<div id="result"></div>
<script>
//兼容IE8-浏览器
test.onmousedown =function(){
if(this.dragDrop){
this.dragDrop();
}
}
test.ondragstart = function(e){
e = e || event;
//兼容firefox浏览器
e.dataTransfer.setData(&#39;text&#39;,&#39;&#39;);
e.dataTransfer.effectAllowed = &#39;all&#39;;
}
target1.ondragenter = target2.ondragenter =target3.ondragenter =target4.ondragenter =function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}this.style.background = &#39;red&#39;;
}
target1.ondragover = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
e.dataTransfer.dropEffect = &#39;none&#39;;
}
target2.ondragover = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
e.dataTransfer.dropEffect = &#39;move&#39;;
}
target3.ondragover = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
e.dataTransfer.dropEffect = &#39;copy&#39;;
}
target4.ondragover = function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
e.dataTransfer.dropEffect = &#39;link&#39;;
}
target1.ondragleave = target2.ondragleave =target3.ondragleave =target4.ondragleave =function(e){
e = e || event; this.style.backgroundColor = &#39;lightblue&#39;;
}
target1.ondrop = target2.ondrop =target3.ondrop =target4.ondrop =function(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
this.style.backgroundColor = &#39;orange&#39;;
}
</script>

Ce qui précède est le glisser-déposer natif JavaScript introduit par l'éditeur. J'espère qu'il vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Je voudrais également vous remercier tous pour votre soutien au site Web PHP chinois !

Pour une compréhension plus approfondie du glisser-déposer natif JavaScript, veuillez prêter attention au site Web PHP chinois pour les articles connexes !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn