【问题标题】:How to implement drag and drop so dragging child element will drag whole parent element如何实现拖放,以便拖动子元素将拖动整个父元素
【发布时间】:2016-07-16 01:41:24
【问题描述】:

我正在为 wordpress 开发一个媒体导入插件。我正在尝试实现拖放功能来重新排序用户导入的媒体元素(音频和/或图像)。我有一个<div> 标签(我们将它们称为media divs),它最多可容纳三个其他<span><img><audio> 标签。因此,我将所有已导入的媒体资产显示在一行中,并希望能够拖放以重新排序 媒体 div。我使用 html5 实现基本的拖放没有问题。我的问题是,现在当我单击 media divs 内的媒体子元素(<audio><img>)时,子元素是拖动事件的目标。有什么办法可以将拖动事件的目标重置为父元素,以便我拖动整个 media div 而不仅仅是媒体元素?我查看了e.stopPropogation() 并阅读了冒泡和捕获,但我尝试使用这些的每一种方式,它都不能解决我的问题。有什么我想念的吗?如果可能,我宁愿避免使用 jQuery,并且绝对不能使用任何库或框架。
TL;DR:当单击子元素时,如何使父元素成为拖动事件的目标?

<div class="npr-import-media npr-import-audio npr-import-images" id="media-container">

    <div class="npr-import-media-container" draggable="true">
        <audio src="<?php echo $audio->format->mp4->{'$text'}; ?>" controls></audio>
        <span class="npr-media-delete">X</span>
    </div>

    <div class="npr-import-image-container npr-import-media-container" draggable="true">
        <img class="npr-import-image" src="<?php echo $image->src; ?>" >
        <span class="npr-import-image-caption"><?php echo $image->caption->{'$text'} ?></span>
        <span class="npr-media-delete">X</span>
    </div>

    <div class="npr-import-add-media npr-import-media-container">
        Add Media+
    </div>

</div>

这是我的代码的 HTML 部分。最初有更多的 php 功能来循环原始源材料以显示从原始文章中导入的所有媒体元素,但我认为没有必要包含它。

【问题讨论】:

  • 为什么不让父元素可拖动?
  • @MustafaShujaie 父元素(media div)是可拖动的。我设置了draggable = true。但是当我点击 media div 的子元素时,它也必须是可拖动的,因为它变成了被拖动的对象,而不是整个 media div
  • 请插入您的 HTML 标记
  • 据我了解,您想重新排序媒体 div 元素,对吗?此外,您不需要子元素是可拖动的。当您单击子元素并开始拖动时,事件将冒泡到父元素,并由分配给它的事件处理程序处理。
  • @MustafaShujaie 这也是我的想法,但无论我尝试启用/禁用冒泡或捕获它的方式有多少都不会改变任何东西。而且无论我如何尝试使用stopPropagation(),它都不会改变任何东西。我想现在我要使用捕获,在ondragstart 事件开始时,我会检查ev.target.className 是否是我想要的。如果不是,我将退出该功能并让捕获处理其余的工作。

标签: javascript html drag-and-drop


【解决方案1】:

您可以将ondragstart 事件的处理程序设置为返回false,如下所示:

<div class="npr-import-media npr-import-audio npr-import-images" id="media-container">
    <div class="npr-import-image-container npr-import-media-container" draggable="true" ondragstart="drag(event)" style="border:1px solid blue;padding:10px;">
        <img class="npr-import-image" src="img.jpg" >
        <span class="npr-import-image-caption">Caption</span>
        <span class="npr-media-delete">X</span>
    </div>

    <div class="npr-import-add-media npr-import-media-container">
        Add Media+
    </div>
</div>
<script>
function drag(e) {
    console.log(e);
}
var images = document.getElementsByTagName('img');
for(i = 0 ; i < images.length; i++) 
    images[i].ondragstart = function() { return false; }
</script>

在控制台输出上你可以看到:

>> DragEvent {isTrusted: true, dataTransfer: DataTransfer, screenX: 66, screenY: 161, clientX: 66…}

更新 通过上面的 html 属性在父元素上设置拖动事件处理程序,或者通过如下代码附加事件侦听器:

document.getElementById('draggable').addEventListener('dragstart', function(e) {
   console.log(e);
});

【讨论】:

  • 这与我需要的很接近,但是现在当您尝试拖动图片时,什么也没有发生。有没有办法让它冒泡到顶部,以便父元素成为目标?
【解决方案2】:

我也遇到了同样的问题,无法解决img标签,所以切换到div。

你可以使用

<div style="background-image: url('img.jpg')"></div>

而不是

<img class="npr-import-image" src="img.jpg" >

【讨论】:

    【解决方案3】:

    我也遇到了这个问题。我在没有 javascript 的情况下通过简单地将 draggable="false" 添加到每个子元素来解决它。

    <div class="npr-import-image-container npr-import-media-container" draggable="true" ondragstart="drag(event)" style="border:1px solid blue;padding:10px;">
        <img draggable="false" class="npr-import-image" src="img.jpg" >
        <span draggable="false" class="npr-import-image-caption">Caption</span>
        <span draggable="false" class="npr-media-delete">X</span>
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多