我有带有锚元素的项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
答案 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>