We have a top nav bar on the website that we are trying to use spans to create slightly different versions for desktops vs tablets.
Each nav bar item has a full url to handle folks with JS disabled and we use JS to intercept the click and open a flyout menu panel. But if we put spans within the a href
link the js intercept stops working and user gets sent to the default link.
Our HTML is below, the first link fail to intercept and goes to the default url, the second link opens the menu as desired.
<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>
Our JS snippet is below. It is part of a bigger event delegation script, that provides different functions for different links on a page. Note: we don't use JQuery, have simply set $ to function as 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
The openNav()
function checks to see the nav panel is open by checking style.maxHeight
and closes it if open, otherwise sets all nav panel to closed value and then open target nav panel.
Add additional condition for span
whose parent node is a
like below.
else if (e.target.nodeName === 'SPAN' && e.target.parentNode.nodeName === "A")
.
Take new variable as let target = e.target.parentNode;
, and replace use it instead of e.target
. Try like below.
// 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>
You can combine if
& else if
in single if
as well. Try improved code as below.
// 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>