1

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

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

本质上,有很多滑动正在进行,所以默认的身体滚动行为需要被淘汰。滑动时左右滑动的页面令人愤怒。自然,我必须将事件侦听器添加到外部容器中。无法避免。

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

谢谢你的帮助。

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;
});
4

2 回答 2

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();
    }
});
于 2012-12-21T10:49:35.117 回答
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();
    }
});
于 2012-12-21T11:10:34.600 回答