链接内的跨度会导致js事件传播失败



我们在网站上有一个顶部导航栏,我们正试图使用span为台式机和平板电脑创建略有不同的版本。

每个导航栏项目都有一个完整的url来处理禁用JS的用户,我们使用JS拦截点击并打开弹出菜单面板。但是,如果我们在a href链接中放置跨度,js拦截将停止工作,用户将被发送到默认链接。

我们的HTML如下,第一个链接无法拦截并转到默认url,第二个链接根据需要打开菜单。

<a href="example.com/link1.htm" id="nvbtn1" class="tba"><span class="sf">Full Desktop Title</span><span class="st">Lil Title</span></a>
<a href="example.com/link2.htm" id="nvbtn2" class="tba">Medium Title</a>

我们的JS片段如下。它是更大的事件委派脚本的一部分,为页面上的不同链接提供不同的功能。注意:我们不使用JQuery,只是将$设置为getElementById。

// overall event delegation
$('mstrwrap').addEventListener('click', function(e) {
// set eventlisteners for all A HREF links
if (e.target.nodeName === 'A') {
// check if is navbar link
if ((e.target.id) && (e.target.id.includes('nvbtn'))) {
// disable click through and determine matching nav panel
e.preventDefault();
const nvpnl = e.target.id;
const lk = 'nav' + nvpnl.match(/d+/g);
// open nav panel
openNav(lk, nvpnl);
}
// end if navbar link
// 140 more lines of event delegation
}
// end set eventListeners
});
// end masterwrap event delegation

openNav()功能通过检查style.maxHeight来检查导航面板是否打开,如果打开则关闭,否则将所有导航面板设置为关闭值,然后打开目标导航面板。

为父节点为aspan添加附加条件,如下所示。

else if (e.target.nodeName === 'SPAN' && e.target.parentNode.nodeName === "A")

将新变量取为let target = e.target.parentNode;,并替换为使用它而不是e.target。尝试如下。

// overall event delegation
document.getElementById('mstrwrap').addEventListener('click', function(e) {
// set eventlisteners for all A HREF links
if (e.target.nodeName === 'A') {
// check if is navbar link
if ((e.target.id) && (e.target.id.includes('nvbtn'))) {
// disable click through and determine matching nav panel
e.preventDefault();
const nvpnl = e.target.id;
const lk = 'nav' + nvpnl.match(/d+/g);
// open nav panel
openNav(lk, nvpnl);
}
// end if navbar link
// 140 more lines of event delegation
}
// add additional condition for span whose parent node is <a>.
else if (e.target.nodeName === 'SPAN' && e.target.parentNode.nodeName === "A") {
// set target variable as parent node and replace e.target with this variable
let target = e.target.parentNode;
// check if is navbar link
if ((target.id) && (target.id.includes('nvbtn'))) {
// disable click through and determine matching nav panel
e.preventDefault();
const nvpnl = target.id;
const lk = 'nav' + nvpnl.match(/d+/g);
// open nav panel
openNav(lk, nvpnl);
}
// end if navbar link
// 140 more lines of event delegation
}
// end set eventListeners
});
// end masterwrap event delegation
function openNav(lk, nvpnl) {
console.log(lk, nvpnl);
}
<div id='mstrwrap'>
<a href="example.com/link1.htm" id="nvbtn1" class="tba"><span class="sf">Full Desktop Title</span><span class="st">Lil Title</span></a>
<a href="example.com/link2.htm" id="nvbtn2" class="tba">Medium Title</a>
</div>


您可以将if&CCD_ 10在单个CCD_。请尝试以下改进的代码。

// overall event delegation
document.getElementById('mstrwrap').addEventListener('click', function(e) {
// set eventlisteners for all A HREF links
if (e.target.nodeName === 'A' || (e.target.nodeName === 'SPAN' && e.target.parentNode.nodeName === "A")) {
// if target is <a> then use it otherwise use parent node
let target = e.target.nodeName === 'A' ? e.target : e.target.parentNode;

// NOTE : use target variable instead of e.target

// check if is navbar link
if ((target.id) && (target.id.includes('nvbtn'))) {
// disable click through and determine matching nav panel
e.preventDefault();
const nvpnl = target.id;
const lk = 'nav' + nvpnl.match(/d+/g);
// open nav panel
openNav(lk, nvpnl);
}
// end if navbar link
// 140 more lines of event delegation
}
// end set eventListeners
});
// end masterwrap event delegation
function openNav(lk, nvpnl) {
console.log(lk, nvpnl);
}
<div id='mstrwrap'>
<a href="example.com/link1.htm" id="nvbtn1" class="tba"><span class="sf">Full Desktop Title</span><span class="st">Lil Title</span></a>
<a href="example.com/link2.htm" id="nvbtn2" class="tba">Medium Title</a>
</div>

最新更新