将事件侦听器添加到父级已禁用事件的子级

时间:2012-12-21 10:32:41

标签: javascript events default parent children

这里很奇怪。早些时候,我正在努力防止我正在构建的iOS webapp中的默认touchmove行为。添加事件监听器并防止传播很容易,但我需要将默认行为添加回其中一个子节点。据我所知,由于父母被禁用,孩子将永远不会注册该事件。

所以我需要一个解决方案。

基本上,有很多刷卡正在进行,因此默认的身体滚动行为需要被淘汰。刷卡时滑动的页面令人气愤。当然,我必须将事件监听器添加到外部容器中。无法避免。

如何将默认的浏览器控制行为添加回其中一个孩子?我不想用自己的物理学和所有物理来伪造它。

感谢您的帮助。

HTML:

<div id="mainPanel"> <!-- add event listener and preventDefault(); -->
    <div id="nonScrollingPanel></div>
    <div id="scrollingPanel></div> <!-- add event listener and re-enable default -->
</div>

JavaScript的:

$bod.on('touchmove', '#mainPanel', function(event){

    event.preventDefault();
});

$('#mainPanel').on('touchmove', '#scrollingPanel', function(){

    return true;
});

2 个答案:

答案 0 :(得分:0)

简单地说,最简单的方法是在preventDefault()之前检查它是否不是孩子。

普通JS中的一个例子:

HTML:

<div id="parent">
    parent
    <div id="child">
        child
    </div>
</div>​

JS:

var parent = document.getElementById('parent');

parent.addEventListener('click', function(e) {
    // Gets closest div
    var div = function closest(el) {
        if (el.tagName === 'DIV') {
            return el;
        }
        else {
            return closest(el.parentNode);
        }
    }(e.target);

    if (div.id !== 'child') {
        e.preventDefault();
    }
});

Jsfiddle示例:http://jsfiddle.net/Ralt/yxxmx/

按照你的例子,它就像:

$bod.on('touchmove', '#mainPanel', function(event){
    if ($(event.target).closest('div')[0].id !== 'scrollingPanel') {
        event.preventDefault();
    }
});

答案 1 :(得分:0)

这不能按预期工作的原因是jQuery运行所有事件处理程序,除非你停止在其中一个中传播。在您的示例中,两个事件处理程序都将运行。

这是一个我不喜欢的解决方案,因为您实际上可能希望事件为了其他目的而传播。

$('#main-panel').on('touchmove', function(e) {
    e.preventDefault();
});

$('#scrolling-panel').on('touchmove', function(e) {
    e.stopPropagation();
});​

所以这就是我要做的,除非iOS有一些特殊的元标记来禁用页面滑动:

$('#main-panel').on('touchmove', function(e) {
    if (!$('#scrolling-panel')[0].contains(e.target)) {
        e.preventDefault();
    }
});