javascript - HTML 使元素无效放置目标

标签 javascript jquery html

我有一个应用程序,用户可以在其中将内容从一个列表拖放到另一个列表。每个列表都有许多 div 作为元素,每个元素都有自己的子元素。我依靠父级 div 的 id 来检测执行放置的位置,但有时子级会消耗事件,因为当时光标位于它们上方。有没有办法通过向这些子项添加类似 droptarget="false" 的内容来避免这种情况?

我认为代码没有必要(而且太多了),但无论如何:

<link rel="stylesheet" href="{{rootURL}}css/assembler.css">

<div class="width_match_parent box_sizing_border flex_container_row flex_align_item_start  material_blue_500 padding_large">
    <div id="template_assembler_div_card_list" class="layout_weight_2 box_sizing_border flex_container_column padding_large">
        <!-- ======================================================================================== -->
        <div id="card_1" draggable="true" class="assembler_workflow_card card blue-grey darken-1">
            <div class="card-content white-text" ondragover="return true">
                <span class="card-title">Card Title</span>
                <p>I am a very simple card. I am good at containing small bits of information.
                    I am convenient because I require little markup to use effectively.</p>
            </div>
            <div class="card-action">
                <a href="#">This is a link</a>
                <a href="#">This is a link</a>
            </div>
        </div>
        <!-- ======================================================================================== -->
        <div id="card_2" draggable="true" class="assembler_workflow_card card blue-grey darken-1">
            <div class="card-content white-text">
                <span class="card-title">Card Title</span>
                <p>I am a very simple card. I am good at containing small bits of information.
                    I am convenient because I require little markup to use effectively.</p>
            </div>
            <div class="card-action">
                <a href="#">This is a link</a>
                <a href="#">This is a link</a>
            </div>
        </div>
        <!-- ======================================================================================== -->
        <div id="card_3" draggable="true" class="assembler_workflow_card card blue-grey darken-1">
            <div class="card-content white-text">
                <span class="card-title">Card Title</span>
                <p>I am a very simple card. I am good at containing small bits of information.
                    I am convenient because I require little markup to use effectively.</p>
            </div>
            <div class="card-action">
                <a href="#">This is a link</a>
                <a href="#">This is a link</a>
            </div>
        </div>
        <!-- ======================================================================================== -->
        <div id="card_4" draggable="true" class="assembler_workflow_card card blue-grey darken-1">
            <div class="card-content white-text">
                <span class="card-title">Card Title</span>
                <p>I am a very simple card. I am good at containing small bits of information.
                    I am convenient because I require little markup to use effectively.</p>
            </div>
            <div class="card-action">
                <a href="#">This is a link</a>
                <a href="#">This is a link</a>
            </div>
        </div>
        <!-- ======================================================================================== -->
        <div id="card_5" draggable="true" class="assembler_workflow_card card blue-grey darken-1">
            <div class="card-content white-text">
                <span class="card-title">Card Title</span>
                <p>I am a very simple card. I am good at containing small bits of information.
                    I am convenient because I require little markup to use effectively.</p>
            </div>
            <div class="card-action">
                <a href="#">This is a link</a>
                <a href="#">This is a link</a>
            </div>
        </div>
        <!-- ======================================================================================== -->
    </div>
    <div class="layout_weight_1 box_sizing_border flex_container_column flex_justify_content_start padding_large">
        <ul class="collection">
            <li draggable="true" class="collection-item ">Alvin</li>
            <li draggable="true" class="collection-item ">Alvin</li>
            <li draggable="true" class="collection-item ">Alvin</li>
            <li draggable="true" class="collection-item ">Alvin</li>
        </ul>
        <p draggable="true">This is a draggable paragraph.</p>
    </div>
</div>

和js:

ANIMATION_DIRECTION_UP = -1 ;
ANIMATION_DIRECTION_DOWN = 1 ;

// ============================================================================================== //
// ============================================================================================== //
// ============================================================================================== //

var initialized = false ;
var dragging = false ;
var animating = false ;

// ============================================================================================== //
// ============================================================================================== //
// ============================================================================================== //

var workflow_cards_div ;
workflow_cards = [] ;
var dragged_workflow_card ;
var current_drag_target ;
var current_animation_direction ;

function WorkflowCard(element) {
    this.element = element ;
    this.width = element.outerWidth ;
    this.height = element.outerHeight ;
}

WorkflowCard.prototype = {

}

function get_workflow_card(id) {
    // console.log(workflow_cards.length) ;
    for (var i = 0 ; i < workflow_cards.length ; i++) {
        // console.log(i + ':' + workflow_cards[i].element)
        if (workflow_cards[i].element.id == id) {
            return workflow_cards[i] ;
        }
    }
}

function get_animation_targets(workflow_card) {
    if (current_animation_direction == ANIMATION_DIRECTION_UP) {
        return get_animation_workflow_cards(workflow_card, true) ;
    } else {
        return get_animation_workflow_cards(workflow_card, false) ;
    }
}

function get_animation_workflow_cards(workflow_card, d) {
    l = [] ;
    var add = d ;
    for (var i = 0 ; i < workflow_cards.length ; i++) {
        if (workflow_cards[i].element.id == workflow_card.element.id) {
            add = !d ;
        }
        if (add) {
            l.push(workflow_cards[i]) ;
        }
    }
    return l ;
}

// ============================================================================================== //
// ============================================================================================== //
// ============================================================================================== //

function initialize() {
    if (!initialized) {
        initialized = true ;
        get_all_workflow_cards() ;
    }
}

function get_all_workflow_cards() {
    $('div.assembler_workflow_card').each(function(index, element) {
        console.log(Object.prototype.toString.call(element)) ;
        workflow_cards.push(new WorkflowCard(element)) ;
    }) ;
    console.log(Object.prototype.toString.call($('#card_1')))
    console.log($('#card_1')) ;
}

function initialize_dimensions() {
    workflow_card_div = document.getElementById('template_assembler_div_card_list') ;
}

// ============================================================================================== //
// ============================================================================================== //
// ============================================================================================== //

document.addEventListener("drag", function(event) {
    initialize() ;
    if (!dragging) {
        if (get_workflow_card(event.target.id)) {
            dragged_workflow_card = get_workflow_card(event.target.id) ;
            console.log('being dragged:' + dragged_workflow_card.element.id) ;
            dragging = true ;
        }
    }
}, false);

document.addEventListener("dragover", function(event) {
    event.preventDefault() ;
}, false);

document.addEventListener("dragenter", function(event) {
    console.log('entering: ' + event.target.id)
    target = get_workflow_card(event.target.id) ;
    if (target == undefined) {

    }
    if (target.element.id != dragged_workflow_card.element.id) {
        if (!animating) {
            animating = true ;
            console.log('dragenter ' + target.element.id) ;
            position = $('#' + target.element.id).position() ;
            center = {
                x: position.left + target.width / 2,
                y: position.top + target.height / 2
            }
            drag_position = {
                x: event.screenX,
                y: event.screenY
            }
            if (drag_position.y < center.y) {
                // from above, move them down
                console.log('from above, move them down') ;
                current_animation_direction = ANIMATION_DIRECTION_DOWN ;
            } else {
                // from below, move them up
                console.log('from below, move them up') ;
                current_animation_direction = ANIMATION_DIRECTION_UP ;
            }
            animation_targets = get_animation_targets(target) ;
            // console.log(animation_targets) ;
            for (var i = 0 ; i < animation_targets.length ; i++) {
                console.log(animation_targets[i]) ;
                console.log('animating ' + animation_targets[i].element.id)
                $('#' + animation_targets[i].element.id).animate({
                    "top": "+=100"
                }) ;
                // document.getElementById(animation_targets[i].element.id).animate([
                //  {transform: 'translateY(' + current_animation_direction * dragged_workflow_card.height + 'px)'}
                // ],
                // {
                //  duration: 500,
                //  iterations: 1,
                //  easing: "ease-in-out",
                // }) ;
            }
        }
    }
}, false);

document.addEventListener("dragleave", function( event ) {
    if (!event.target) {
        return ;
    }
    target = get_workflow_card(event.target.id) ;
    if (target != undefined) {
        // center = target
    }
}, false);

document.addEventListener("drop", function( event ) {
    event.preventDefault() ;
    dragging = false ;
}, false);

// ============================================================================================== //
// ============================================================================================== //
// ============================================================================================== //

$(document).ready(function() {
}) ;

最佳答案

根据您的问题,我认为您希望逻辑位于 drop 事件监听器中,但您似乎将其放在 dragenter 事件中听众。无论如何,您可以通过比较事件 targetcurrentTarget 属性来检测父元素或子元素是否触发了事件。 currentTarget 始终是定义了事件监听器的元素。

在您的情况下,您可能希望将拖动事件监听器添加到您关心的父元素中,而不是将它们添加到文档中。然后,您可以通过查看 event.currentTarget 或将 id 存储在事件监听器回调中来确定父元素的 id。

关于javascript - HTML 使元素无效放置目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42148007/

相关文章:

javascript - JavaScript 幻灯片放映中的淡入淡出过渡

javascript - JS : I am trying to understand event emitters vs event listeners

javascript - 谷歌地图 infoWindow 只加载标记上的最后一条记录

javascript - 单击元素时 Bootstrap 下拉菜单不会关闭

javascript - 解析 JSON 后元素消失

html - 垂直对齐标题元素

python - 将 URL 链接与 Django 变量连接起来

javascript - 逐步使用 Node.js 创建自定义应用程序

javascript - 当用户使用 jquery 不断单击按钮时需要 append html 元素

jquery - 如何在 Bootstrap 数据表插件上对日期格式 d/m/y 进行排序?