Edit
After rereading the question, I think that OP has over complicated things (as have I obviously). Added a simpler version of Demo 1 labeled Demo 2. And added Demo 3 which is solution that uses no JavaScript/jQuery just CSS.
Capture Phase
When you need fine grained control over the event chain .addEventListener() is better suited to handle particular aspects like firing the event on the capture phase instead of the bubbling phase. The reason why is because li.tag will be before a.link on the first phase (i.e. capture phase) of the event chain. We assign capture or bubbling phase by assigning the appropriate boolean value to the third parameter:
document.addEventListener('click', function(e) {...}, false);
This is default, which is set at false for the bubbling phase.
document.addEventListener('click', function(e) {...}, true);
This will make the registered object (e.g.document in this example) listen and act on the capture phase.
The following demo -- during capture phase -- will:
- assign the clicked
li.tag as the event.target...
- ...then invoke
e.stopPropagation() so the a.link nested within the li.tag will not be included in the event chain. The bubbling phase is skipped as well.
- Instead, this
a.link becomes e.target on a new event chain because the trigger method .click() is invoked on it.
Test
The 3rd link of List0 tests whether a.link is indeed triggered by .click() or firing during capture or bubbling phase, or is the event.target. Because each a.link in List0 has pointer-events:none which makes a.link oblivious to any mouse or click event from a user, we can conclude:
that any activation of said a.link is entirely dependant upon its parent li.tag being clicked by a user.
during the capture phase, no click event will reach a.link due to e.stopPropagation() and pointer-events:none it can't be e.target.
bubbling phase isn't even there for a.link because of e.stopPropagation()
As that event chain dies off .click() is fired and a.link goes off like a second stage rocket
When clicking anywhere on the 3rd list item we get these results:
- log:
Target: LI
- Does not jump to List2
When clicking the first or second list item of List0 we get these results:
- log:
LinkID: {0-1 or 0-2}
- log:
Target: A
- log:
Target: LI
- Jumps to List1 or List2
Errors
In the Fiddle, there were 2 instances of invalid HTML:
Error 1: <ui>
Correct: <ul>
Error 2: All <a> had the same id, all id must be unique
<a class="link_em" href="?l=1" id="1">List1</a>
<a class="link_em" href="?l=2" id="1">List2</a>
Correct:
<a href='#l1-1' class='link' id='0-1'></a>
<a href='#l1-2' class='link' id='0-2'></a>
You'll notice that the classes and ids in HTML are slightly different, but it'll be ok to change back to your own as long as you mind the errors mentioned above.
Demo 1
document.addEventListener('click', function(e) {
if (e.target.className === 'tag') {
e.stopPropagation();
var link = e.target.querySelector('a');
console.log('ID: ' + link.id);
link.click();
console.log('Target: ' + e.target.tagName);
return false;
} else {
console.log('Target: ' + e.target.tagName);
return false;
}
}, true);
ul {
height: 90px;
outline: 1px solid red;
}
li {
height: 30px;
outline: 1px solid blue;
cursor: pointer
}
.link {
display: block;
width: 10px;
height: 10px;
background: red;
pointer-events: none;
cursor: default;
position: relative;
z-index: 1;
}
b {
float: left;
}
hr {
margin-bottom: 1500px
}
.as-console {
position: fixed;
bottom: 30px;
right: 0;
max-width: 150px;
color: blue;
}
.top {
width: 100px;
pointer-events: auto;
}
<h1>Capture Phase Demo</h1>
<details>
<summary>Test</summary>
<p>Third list item is not a .tag.</p>
<dl>
<dt>Results:</dt>
<dd>Logged: "Target: LI"(or "Target: "B")</dd>
<dd>Did not log: "ID:0-2"</dd>
<dd>Did not jump to List2</dd>
<dt>Conclusion:</dt>
<dd>Links on List0 do not respond to mouse or click events from user. Therefore in order to jump from List0 the link must be triggered programmatically.</dd>
</dl>
</details>
<h2 id='l1-0'>List0</h2>
<ul>
<li class='tag'>
<a href='#l1-1' class='link' id='0-1'>List1</a>
</li>
<li class='tag'>
<a href='#l1-2' class='link' id='0-2'>List2</a>
</li>
<li>
<a href='#l1-2' class='link' id='0-2'>Test</a>
</li>
</ul>
<b>1500px to List1 </b>
<hr>
<h2 id='l1-1'>List1</h2>
<ul>
<li><a class='top' href='#l1-0'>Back to Top</a></li>
<li>Item</li>
</ul>
<b>1500px to List2 </b>
<hr>
<h2 id='l1-2'>List2</h2>
<ul>
<li>
<a class='top' href='#l1-0'>Back to Top</a>
</li>
<li>Item</li>
</ul>
Demo 2
document.addEventListener('click', function(e) {
if (e.target.className === 'tag') {
e.stopPropagation();
e.target.querySelector('a').click();
}
}, true);
ul {
height: 100px;
outline: 1px solid red
}
li {
height: 100%;
cursor:pointer;
}
<h1 id='list0'>List0</h1>
<ul>
<li class='tag'>
<a href='#list1'>List1</a>
</li>
</ul>
<hr>
<h1 id='list1'>List1</h1>
<ul>
<li class='tag'>
<a href='#list0'>List0</a>
</li>
Demo 3
ul {
height: 100px;
outline: 1px solid blue
}
li {
height: 100%;
padding: 0
}
a {
display: block;
height: 100%;
width: 100%;
}
<h1 id='list0'>List0
<h1>
<ul>
<li>
<a href='#list1'>List1</a>
</li>
</ul>
<hr>
<h1 id='list1'>List1
<h1>
<ul>
<li>
<a href='#list0'>List0</a>
</li>
</ul>