防止在拖动/按住时单击超链接

时间:2018-07-01 18:59:32

标签: javascript hyperlink draggable preventdefault interact.js

我有带有锚元素的项div元素作为子元素。锚点子项的大小拉伸了父项元素。

我已使item元素可通过库interact.js拖动。当项目保持300ms或更长时间时,它们将变为可拖动状态。问题在于,释放拖动时会触发子项的锚链接。

在保持/拖动父元素时,如何防止孩子触发超链接?

这是问题的一个小例子

let items = document.getElementsByClassName("item");

// add class .draggable to each item
for(var i = 0; i < items.length; i++)
{
   items[i].classList.add("draggable");
}

// target elements with the "draggable" class
interact('.draggable').draggable({
	autoScroll: true,
	hold: 300,
	// call this function on every dragmove event
	onmove: dragMoveListener,
	// call this function on every dragend event
	onend: function (event) {
		var target = event.target;
		target.style.webkitTransform =
		target.style.transform =
		'translate(0px, 0px)';

		target.setAttribute('data-x', 0);
		target.setAttribute('data-y', 0);
	}
});

// this function is calles on every dragmove event
function dragMoveListener (event) {
	var target = event.target,
		 // keep the dragged position in the data-x/data-y attributes
		 x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
		 y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

	// translate the element
	target.style.webkitTransform =
		target.style.transform =
		'translate(' + x + 'px, ' + y + 'px)';

	// update the posiion attributes
	target.setAttribute('data-x', x);
	target.setAttribute('data-y', y);
};



interact('.dropzone').dropzone({

	
  ondropactivate: function (event) {
    event.target.classList.add('drop-active');
  },
	
  ondragenter: function (event) {
	  var draggableElement = event.relatedTarget,
			dropzoneElement = event.target;

	  // feedback the possibility of a drop
	  dropzoneElement.classList.add('drop-target');
	  draggableElement.classList.add('can-drop');
  },
	
  ondragleave: function (event) {
	  // remove the drop feedback style
	  event.target.classList.remove('drop-target');
	  event.relatedTarget.classList.remove('can-drop');
  },
	
  ondrop: function (event) {
	  //delete Bookmark here!
	  event.relatedTarget.classList.add('drop-ok');
  },
	
  ondropdeactivate: function (event) {
	  // remove active dropzone feedback
	  event.target.classList.remove('drop-active');
	  event.target.classList.remove('drop-target');
  }
});
body {
  background-color: #EDEFF3;
  padding: 40px 48px;
}

.item {
  display: inline-block;
  margin: 8px;
  background-color: RGBA(255, 255, 255, 1);
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  border-radius: 10px;
  z-index: 999;
}
.item a {
  position: relative;
  display: inline-block;
  border-radius: 10px;
  line-height: 40px;
  padding: 0 32px 0 48px;
  font-weight: 400;
  text-decoration: none;
  font-size: 13px;
  color: black;
  font-size: 14px;
}
.item a .dott {
  position: absolute;
  top: 12px;
  left: 20px;
  height: 16px;
  width: 16px;
  background-color: tomato;
  border-radius: 100%;
}
.item.can-drop a {
  text-decoration: line-through;
}
.item.drop-ok {
  display: none;
}

.category {
  display: flex;
  flex-wrap: wrap;
  position: relative;
  align-items: flex-start;
  background-color: RGBA(127, 135, 147, 0.2);
  margin: 16px;
  padding: 8px;
}

.dropzone {
  height: 20%;
  width: 100%;
  position: fixed;
  bottom: 0;
  left: 0;
  background-color: tomato;
  opacity: 0;
}
.dropzone.drop-active {
  opacity: 1;
}
.dropzone.drop-target {
  background-color: #F15B52;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs@1.3.4/dist/interact.min.js"></script>
<div class="category">
	
	<div class="item">
		<a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
	</div>
	
	<div class="item">
		<a href="https://www.google.com/">
			<span class="dott"></span>
		bookmark</a>
	</div>
	
	<div class="item">
		<a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
	</div>
	
	<div class="item">
		<a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
	</div>
	
	<div class="item">
		<a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
	</div>	
</div>

<div class="dropzone"></div>

这是我目前在Codepen的状态: https://codepen.io/iamrbn/pen/pKGPMz

1 个答案:

答案 0 :(得分:1)

也许不是最优雅的解决方案,但它可行。我的第一次尝试失败了,但我认为我现在有一些可行的方法。我创建了一个标记系统来跟踪事件。请注意,我在可拖动实例中添加了onstart。我必须添加300ms超时以匹配保持时间。尽管保持了300ms,但似乎在按下鼠标时就立即触发了onstart。我不确定您图书馆的那部分是如何工作的;)

无论如何,请等待300毫秒,然后设置拖动标记。请注意,该变量是全局变量,以供参考。在执行此操作之前,请检查您的项目变量范围。您可能想创建一个公共对象,以防止全局混淆。

我将click事件侦听器添加到每个链接。单击后,请检查保持标志状态。如果是阻力,则阻止该事件。否则,请继续注册点击。注意:我曾尝试将此标志评估器代码添加到可拖动实例中的onend方法中,但是onend原来是一个mouseup事件,在click之前触发。因此,评估需要通过click事件来进行。在范围内执行此操作的最佳方法是向每个链接添加click事件。

哇!天哪,大概花了一个小时。让我知道它是否有效:)

let items = document.getElementsByClassName("item");

// add class .draggable to each item
for (var i = 0; i < items.length; i++) {
  items[i].classList.add("draggable");
  items[i].children[0].addEventListener('click',function(e){
  if(drag){
    drag = false;
    e.preventDefault()
    }
  });
}

var drag = false;

// target elements with the "draggable" class
interact('.draggable').draggable({
  autoScroll: true,
  hold: 300,
  // call this function on every dragmove event
  onstart: function(){
    setTimeout(function(){
      drag = true;
    },300);
  },
  onmove: dragMoveListener,
  // call this function on every dragend event
  onend: function(event) {
  
    var target = event.target;
    target.style.webkitTransform =
      target.style.transform =
      'translate(0px, 0px)';

    target.setAttribute('data-x', 0);
    target.setAttribute('data-y', 0);
  }
});

// this function is calles on every dragmove event
function dragMoveListener(event) {
  var target = event.target,
    // keep the dragged position in the data-x/data-y attributes
    x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
    y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

  // translate the element
  target.style.webkitTransform =
    target.style.transform =
    'translate(' + x + 'px, ' + y + 'px)';

  // update the posiion attributes
  target.setAttribute('data-x', x);
  target.setAttribute('data-y', y);
};



interact('.dropzone').dropzone({


  ondropactivate: function(event) {
    event.target.classList.add('drop-active');
  },

  ondragenter: function(event) {
    var draggableElement = event.relatedTarget,
      dropzoneElement = event.target;

    // feedback the possibility of a drop
    dropzoneElement.classList.add('drop-target');
    draggableElement.classList.add('can-drop');
  },

  ondragleave: function(event) {
    // remove the drop feedback style
    event.target.classList.remove('drop-target');
    event.relatedTarget.classList.remove('can-drop');
  },

  ondrop: function(event) {
    //delete Bookmark here!
    event.relatedTarget.classList.add('drop-ok');
  },

  ondropdeactivate: function(event) {
    // remove active dropzone feedback
    event.target.classList.remove('drop-active');
    event.target.classList.remove('drop-target');
  }
});
body {
  background-color: #EDEFF3;
  padding: 40px 48px;
}

.item {
  display: inline-block;
  margin: 8px;
  background-color: RGBA(255, 255, 255, 1);
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  border-radius: 10px;
  z-index: 999;
}

.item a {
  position: relative;
  display: inline-block;
  border-radius: 10px;
  line-height: 40px;
  padding: 0 32px 0 48px;
  font-weight: 400;
  text-decoration: none;
  font-size: 13px;
  color: black;
  font-size: 14px;
}

.item a .dott {
  position: absolute;
  top: 12px;
  left: 20px;
  height: 16px;
  width: 16px;
  background-color: tomato;
  border-radius: 100%;
}

.item.can-drop a {
  text-decoration: line-through;
}

.item.drop-ok {
  display: none;
}

.category {
  display: flex;
  flex-wrap: wrap;
  position: relative;
  align-items: flex-start;
  background-color: RGBA(127, 135, 147, 0.2);
  margin: 16px;
  padding: 8px;
}

.dropzone {
  height: 20%;
  width: 100%;
  position: fixed;
  bottom: 0;
  left: 0;
  background-color: tomato;
  opacity: 0;
}

.dropzone.drop-active {
  opacity: 1;
}

.dropzone.drop-target {
  background-color: #F15B52;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs@1.3.4/dist/interact.min.js"></script>
<div class="category">

  <div class="item">
    <a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
  </div>

  <div class="item">
    <a href="https://www.google.com/">
      <span class="dott"></span> bookmark
    </a>
  </div>

  <div class="item">
    <a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
  </div>

  <div class="item">
    <a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
  </div>

  <div class="item">
    <a href="https://www.google.com/"><span class="dott"></span>bookmark</a>
  </div>
</div>

<div class="dropzone"></div>