通过JavaScript使(可能是动态加载的)元素可点击,但优先考虑包含在其中的链接 [英] Make (possibly dynamically loaded) element clickable via JavaScript, but give precedence to links contained within

查看:45
本文介绍了通过JavaScript使(可能是动态加载的)元素可点击,但优先考虑包含在其中的链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am adding a custom data attribute data-js-href to various HTML elements, and these elements should behave just like a link when clicked. If a link within such an element is clicked, the link should take precedence and the data-js-href functionality should be ignored, though. Furthermore, the solution also needs to work with elements that are dynamically added at a later time.

到目前为止,我已经提出了以下解决方案.它基本上检查单击是在链接上还是在链接的任何子元素上进行的(请考虑<a href='…'><img src='…' alt='…' /></a>).

So far, I have come up with the following solution. It basically checks if the click was performed on a link, or any child element of a link (think <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;
    }
});

它可以工作,但感觉非常笨拙,我认为必须有一个更优雅的解决方案.我尝试了类似的方式

It works, but it feels very clumsy, and I think that there has to be a more elegant solution. I tried something along the lines of

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

但无济于事. (我在代码中填充了一些console.log()消息以验证行为.)欢迎任何想法.

but to no avail. (I littered the code with some console.log() messages to verify the behavior.) Any idea is welcome.

推荐答案

您可以通过2个委派事件来执行此操作-无需反向查找,而且它们共享相同的事件也很便宜.缺点是,这是同一个事件,因此将同时触发这两个事件,并且无法通过事件方法将其停止(已经冒泡,这是一个事件,它堆叠了多个伪事件回调并按顺序执行它们-事件已停止但回调仍在继续)这可能是mootools事件与委派实现之间的不一致,但这是另一个问题.

you can do this with 2 delegated events - no reverse lookups and it's cheap as they will share the same event. the downside is, it is the same event so it will fire for both and there's no stopping it via the event methods (already bubbled, it's a single event that stacks up multiple pseudo event callbacks and executes them in order--the event has stopped but the callbacks continue) That's perhaps an inconsistency in mootools event vs delegation implementation but it's a subject of another issue.

目前的解决方法可以是:

Workarounds for now can be:

使2个事件处理程序彼此通信.它将扩展并与添加的任何新els一起使用.

to have the 2 event handlers communicate through each other. It will scale and work with any new els added.

将委托人添加到2个不同的元素上.例如. document.body和#mainWrap.

to add the delegators on 2 different elements. eg. document.body and #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;


    }
});

当我的最初尝试失败并且尽管event.stop触发了两个回调时,也与IRC上的mootools团队的Ibolmo和Keeto讨论了此问题:

Discussed this with Ibolmo and Keeto from the mootools team on IRC as well when my initial attempt failed to work and both callbacks fired despite the event.stop: http://jsfiddle.net/dimitar/J59PD/

因此,在mootools github问题上暂时打开了一张票: https: //github.com/mootools/mootools-core/issues/2105 ,但随后讨论了从库的角度来看正确的做法是什么,以及追求改变工作方式的可行性所以...

As a result, there was briefly a ticket open on the mootools github issues: https://github.com/mootools/mootools-core/issues/2105 but it then went into a discussion of what the right thing to do from the library standpoint is and how viable it is to pursue changing the way things work so...

这篇关于通过JavaScript使(可能是动态加载的)元素可点击,但优先考虑包含在其中的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆