防止重影拖拽不可拖动的元素? [英] Prevent ghost image on dragging non-draggable elements?

查看:410
本文介绍了防止重影拖拽不可拖动的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个使用HTML5拖放API的网站。



但是,为了增加用户体验,我想在出现以下情况时防止出现鬼像用户拖动不可拖动的元素。



进一步,几乎每个元素似乎都  可拖动的  默认。可以单击然后迅速将几乎任何元素拖到浏览器中,这将创建一个幻影图像以及 no-drop 光标。有什么方法可以防止这种行为?




  • draggable = false 没有

  • 用户选择:无不起作用。

  • 指针事件:无不起作用。

  • event.preventDefault()鼠标按下上不起作用。

  • event.preventDefault() dragstart 上也不起作用。



我没主意了到目前为止,事实证明在网上很难找到有关此信息的信息。我发现了以下



我认为这个问题可能与其父节点具有 dragover 的问题有关,并且与之关联的 drop 个事件。



HTML



  ...我还是很傻。 
< body>
...
< div id = backgammon-board-container>
< div class = column id = left-column>
< div class = quadrant id =第三象限>
< div class = point奇数最高点 id = point-13-12>< text> 13< / text>
< div class = checker player-one-checker id = checker-03 draggable = true>< / div>
< / div>
< / div>
< / div>
...
< / div>
< / body>
< / html>



CSS



 #backgammon-board-container {
height:100vh;
宽度:60vw;
头寸:绝对;
右:0;
显示:flex;
}

.column {
height:100%;
显示:flex;
flex-direction:列; / *玩家两个视角的反向列* /
}

#左列{
flex:6;
}

.quadrant {
flex:1;
显示:flex;
}

.point {
flex:1;
padding:10px 0;
显示:flex;
flex-direction:列;
align-items:center;
}

.checker {
z-index:1;
宽度:48像素;
高度:48像素;
边界半径:50%;
}

文字{
位置:固定;
字体家族:影响;
font-size:24px;
颜色:白色;
显示:flex;
justify-content:center;
align-items:center;

用户选择:无;
指针事件:无;
}



JS



  const p1checkers = document.getElementsByClassName('player-one-checker'); 
const p2checkers = document.getElementsByClassName(’player-two-checker’);
const pointClass = document.getElementsByClassName(’point’);

函数setTurn(player){
if(player ==='p1'){
allowCheckerMovement = p1checkers;
disallowCheckerMovement = p2checkers;
} else {
allowCheckerMovement = p2checkers;
disallowCheckerMovement = p1checkers;
}

//为($ i = 0; i allowCheckerMovement [i]启用玩家
的检查器控制。 style.cursor ='指针';
allowCheckerMovement [i] .setAttribute('draggable',true);
allowCheckerMovement [i] .addEventListener('dragstart',start); //对于拖放操作。
allowCheckerMovement [i] .addEventListener(’dragend’,stop); //对于拖放.js
}

//禁用玩家
的检查器控制,用于(var i = 0; i< disallowCheckerMovement.length; i ++) {
disallowCheckerMovement [i] .style.cursor ='default';
disallowCheckerMovement [i] .setAttribute('draggable',false);
disallowCheckerMovement [i] .removeEventListener(’dragstart’,开始); //对于拖放操作。
disallowCheckerMovement [i] .removeEventListener(’dragend’,stop); // for拖放对象
}

//允许拖放
for(var i = 0; i< pointClass.length; i ++){
pointClass [i] .addEventListener('dragover',allowDrop); //对于拖放。js
pointClass [i] .addEventListener(’drop’,dropdOn); //对于拖放.js
}
}

函数start(event){
var checker = event.target;
event.dataTransfer.setData('text / plain',checker.id);
event.dataTransfer.effectAllowed =‘移动’;
window.requestAnimationFrame(function(){
checker.style.visibility ='hidden';
});
}

函数allowDrop(event){
event.preventDefault();
}

函数dropOn(event){
event.preventDefault();
var data = event.dataTransfer.getData(’text / plain’);
event.target.appendChild(document.getElementById(data));
}

函数stop(event){
var element = event.srcElement;
window.requestAnimationFrame(function(){
element.style.visibility ='visible';
});
}


解决方案

这是您的解决方案重新寻找。 ;)



对于任何需要拖动的内容,只需添加启用拖动 CSS类。



< pre class = lang-js prettyprint-override> $('*:not(。enable-drag)')。on('dragstart',function(e){
e.preventDefault();
返回false;
});




I'm creating a website that utilizes the HTML5 Drag and Drop API.

However, to increase the user experience, I'd like to prevent ghost images when a user drags non-draggable elements. Is this even possible?

Further, almost every element seems   " draggable "   by default. One can click and then quickly drag pretty much any element in a browser, which creates a ghost image along with a no-drop cursor. Is there any way to prevent this behaviour?

  • draggable="false" doesn't work.
  • user-select: none doesn't work.
  • pointer-events: none doesn't work.
  • event.preventDefault() on mousedown doesn't work.
  • event.preventDefault() on dragstart doesn't work either.

I'm out of ideas and so far it's proven incredibly difficult to find information about this online. I have found the following thread, but, again, draggable="false" doesn't seem to work in my case.

Below is a screenshot that demonstrates it doesn't work; of course you can't see my cursor in the screenshot, but you can see how I've dragged the numbers to the left despite that.

I believe the issue might have something to do with its parent having dragover and drop events associated with it. I'm still dumbfounded nonetheless.

HTML

...
<body>
  ...
  <div id="backgammon-board-container">
    <div class="column" id="left-column">
      <div class="quadrant" id="third-quadrant">
        <div class="point odd top-point" id="point-13-12"><text>13</text>
          <div class="checker player-one-checker" id="checker-03" draggable="true"></div>
        </div>
      </div>
    </div>
    ...
  </div>
</body>
</html>

CSS

#backgammon-board-container {
  height: 100vh;
  width: 60vw;
  position: absolute;
  right: 0;
  display: flex;
}

  .column {
    height: 100%;
    display: flex;
    flex-direction: column; /* column-reverse for player two perspective */
  }

  #left-column {
    flex: 6;
  }

    .quadrant {
      flex: 1;
      display: flex;
    }

      .point {
        flex: 1;
        padding: 10px 0;
        display: flex;
        flex-direction: column;
        align-items: center;
      }

        .checker {
          z-index: 1;
          width: 48px;
          height: 48px;
          border-radius: 50%;
        }

text {
  position: fixed;
  font-family: impact;
  font-size: 24px;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;

  user-select: none;
  pointer-events: none;
}

JS

const p1checkers = document.getElementsByClassName('player-one-checker');
const p2checkers = document.getElementsByClassName('player-two-checker');
const pointClass = document.getElementsByClassName('point');

function setTurn(player) {
  if (player === 'p1') {
    allowCheckerMovement = p1checkers;
    disallowCheckerMovement = p2checkers;
  } else {
    allowCheckerMovement = p2checkers;
    disallowCheckerMovement = p1checkers;
  }

  // enable checker control for player
  for (var i = 0; i < allowCheckerMovement.length; i++) {
    allowCheckerMovement[i].style.cursor = 'pointer';
    allowCheckerMovement[i].setAttribute('draggable', true);
    allowCheckerMovement[i].addEventListener('dragstart', start); // for drag-and-drop.js
    allowCheckerMovement[i].addEventListener('dragend', stop);    // for drag-and-drop.js
  }

  // disable checker control for player
  for (var i = 0; i < disallowCheckerMovement.length; i++) {
    disallowCheckerMovement[i].style.cursor = 'default';
    disallowCheckerMovement[i].setAttribute('draggable', false);
    disallowCheckerMovement[i].removeEventListener('dragstart', start); // for drag-and-drop.js
    disallowCheckerMovement[i].removeEventListener('dragend', stop);    // for drag-and-drop.js
  }

  // allow drag and drop
  for (var i = 0; i < pointClass.length; i++) {
    pointClass[i].addEventListener('dragover', allowDrop); // for drag-and-drop.js
    pointClass[i].addEventListener('drop', droppedOn);     // for drag-and-drop.js
  }
}

function start(event) {
  var checker = event.target;
  event.dataTransfer.setData('text/plain', checker.id);
  event.dataTransfer.effectAllowed = 'move';
  window.requestAnimationFrame(function(){
    checker.style.visibility = 'hidden';
  });
}

function allowDrop(event) {
  event.preventDefault();
}

function droppedOn(event) {
  event.preventDefault();
  var data = event.dataTransfer.getData('text/plain');
    event.target.appendChild(document.getElementById(data));
}

function stop(event){
  var element = event.srcElement;
  window.requestAnimationFrame(function(){
    element.style.visibility = 'visible';
  });
}

解决方案

This is the solution you're looking for. ;)

For anything that DOES need to be draggable, just add the 'enable-drag' CSS class.

$('*:not(".enable-drag")').on('dragstart', function (e) {
    e.preventDefault();
    return false;
});

这篇关于防止重影拖拽不可拖动的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆