通过JavaScript可以使(可能是动态加载的)元素可点击,但优先考虑其中包含的链接

时间:2011-10-13 20:09:54

标签: javascript mootools

我正在为各种HTML元素添加自定义数据属性data-js-href,这些元素在点击时的行为应该像链接一样。如果单击此类元素中的链接,则链接应优先,但应忽略data-js-href功能。此外,该解决方案还需要使用以后动态添加的元素。

到目前为止,我已经提出了以下解决方案。它基本上检查点击是否在链接或链接的任何子元素上执行(想想<a href='…'><img src='…' alt='…' /></a>)。

// Make all elements with a `data-js-href` attribute clickable
$$('body').addEvent('click:relay([data-js-href])',
                    function(event, clicked) {
    var link = clicked.get('data-js-href');
    if (link && !event.target.match('a')) {
        var parents = event.target.getParents();
        for (var i = 0; i < parents.length && parents[i] != clicked; i++) {
            if (parents[i].match('a')) {
                return;
            }
        }
        document.location.href = link;
    }
});

它有效,但感觉非常笨拙,我认为必须有一个更优雅的解决方案。我尝试了一些

的方法
$$('body').addEvent('click:relay([data-js-href] a)',
                    function(event, clicked) {
    event.stopPropagation();
}

但无济于事。 (我在代码中散布了一些console.log()消息来验证行为。)任何想法都是受欢迎的。

1 个答案:

答案 0 :(得分:2)

你可以通过2个委托事件来做到这一点 - 没有反向查找,并且它很便宜,因为它们将共享同一个事件。缺点是,它是同一个事件,因此它将触发两者并且没有通过事件方法停止它(已经冒泡,它是一个单个事件,它堆叠多个伪事件回调并按顺序执行它们 - 事件已经停止但回调继续)这可能是mootools事件与委托实施的不一致,但它是另一个问题的主题。

现在的解决方法可以是:

让2个事件处理程序相互通信。它将扩展并与任何新增的els一起使用。

在2个不同的元素上添加委托者。例如。 document.body和#mainWrap。

http://jsfiddle.net/dimitar/J59PD/4/

var showURL = function(howLong) {
    // debug.
    return function() {
        console.log(window.location.href);
    }.delay(howLong || 1000);
};

document.id(document.body).addEvents({
    "click:relay([data-js-href] a))": function(e) {
        // performance on lookup for repeat clicks.
        var parent = this.retrieve("parent");
        if (!parent) {
            parent = this.getParent("[data-js-href]");
            this.store("parent", parent);
        }
        // communicate it's a dummy event to parent delegator.
        parent.store("linkEvent", e);
        // let it bubble...
    },
    "click:relay([data-js-href])": function(e) {
        // show where we have gone.
        showURL(1500);
        if (this.retrieve("linkEvent")) {
            this.eliminate("linkEvent");
            return;
        }
        var prop = this.get("data-js-href");
        if (prop)
            window.location.href = prop;


    }
});

在IRC的mootools团队与Ibolmo和Keeto讨论了这个问题,当我最初的尝试无法工作时,尽管event.stop http://jsfiddle.net/dimitar/J59PD/发出了回调,但https://github.com/mootools/mootools-core/issues/2105

结果,在mootools github问题上简短地开了一张票:{{3}}然后它讨论了从图书馆的角度来看正确的做法是什么以及追求的可行性改变事情的运作方式......