我正在尝试使用Javascript来模拟CSS :target
伪类,以便捕获导致页面上的元素被定位的所有事件。我已经确定了3个触发事件:
window.location.hash
已经在初始化时定位了相同ID的元素hashchange
事件独立于上述情况被触发(例如通过window.history
API)场景2作为一个独特的案例非常重要,因为我想要调用click
事件的preventDefault
。此方案的简化代码如下:
$('body').on('click', 'a[href*=#]', function filterTarget(clickEvent){
$(this.hash).trigger('target', [clickEvent]);
});
尝试实施方案3时出现问题:
$(window).on('hashchange', function filterTarget(hashChangeEvent){
$(this.hash).trigger('target', [hashChangeEvent]);
});
如果target
处理程序没有取消方案2的本机行为,则当本机行为导致生成的hashchange
事件时,它将再次被触发。如何过滤掉这些边缘情况?
POST-SOLUTION EDIT:
烘焙的答案持有密钥 - 处理命名空间的hashchange事件,然后根据click处理程序及其preventDefault中处理的逻辑解除绑定并重新绑定处理程序。 I wrote up the full plugin here。
答案 0 :(得分:5)
如果我理解,如果单击一个锚标记,则不希望触发hashchange事件。然后,您可以使用命名空间事件设置逻辑:
$('body').on('click', 'a[href*=#]', function (clickEvent) {
filterTarget(clickEvent,this);
$(window).off('hashchange.filter').on('hashchange.tmp', function () {
$(this).off('hashchange.tmp').on('hashchange.filter', filterTarget);
});
});
$(window).on('hashchange.filter', filterTarget);
function filterTarget(event,elem) {
$(elem?elem.hash:window.location.hash).trigger('target', [event]);
//you could filter depending event.type
alert(event.type + '::'+ (elem?elem.hash:window.location.hash));
}
答案 1 :(得分:1)
如果单击仍然使用片段设置哈希,只需在哈希更改事件中丢弃重复项:
onhashchange=function(e){
if(e.newURL == e.oldURL ){return; }
//do your normal hashchange event stuff below:
};
参考:https://developer.mozilla.org/en-US/docs/Web/API/window.onhashchange
这解决了级联问题,无论调用什么改变。
答案 2 :(得分:0)
似乎你可以使用mousedown而不是click,如果你打算在它上面调用preventDefault。然后可能不会触发哈希转换。