This is a follow-up to this question along with its accepted answer.
This time there is one more list level and the list style item is also highlighted.
Please have a look at this code snippet:
const highlight = (element) => {
element.classList.remove('highlight');
setTimeout(() => {
element.classList.add('highlight');
}, 0);
element.onanimationend = e => {
e.stopPropagation();
element.classList.remove('highlight');
}
}
document.querySelector('body').addEventListener('click', event => {
if (event.target.hash) {
const element = document.querySelector(event.target.hash);
highlight(element);
}
});
@keyframes highlight {
from {
background: red;
}
to {
background: transparent;
}
}
ol {
counter-reset: enumeration;
list-style: none;
}
ol > li {
position: relative;
}
ol > li::before {
position: absolute;
margin-left: -2em;
width: 1em;
counter-increment: enumeration;
content: counter(enumeration) '.';
}
ol > li > ol {
counter-reset: alphabet;
list-style: none;
}
ol > li > ol > li {
position: relative;
}
ol > li > ol > li::before {
position: absolute;
margin-left: -2em;
width: 1em;
counter-increment: alphabet;
content: counter(alphabet, lower-alpha) ')';
}
div.highlight,
ol > li.highlight,
ol > li.highlight::before,
ol > li:has(.highlight)::before {
animation: highlight 5s;
}
<ul>
<li>
<a href="#foo">Foo</a>
<div>
<ul>
<li>
<a href="#foo-1">Foo 1</a>
<ul>
<li><a href="#foo-1-1">Foo 1.1</a></li>
<li><a href="#foo-1-2">Foo 1.2</a></li>
<li><a href="#foo-1-3">Foo 1.3</a></li>
</ul>
</li>
<li><a href="#foo-2">Foo 2</a></li>
<li><a href="#foo-3">Foo 3</a></li>
</ul>
</div>
</li>
<li><a href="#bar">Bar</a></li>
<li><a href="#baz">Baz</a></li>
</ul>
<hr>
<div id="foo">
<h2>Foo</h2>
<ol>
<li id="foo-1">
Foo 1
<ol>
<li id="foo-1-1">Foo 1.1</li>
<li id="foo-1-2">Foo 1.2</li>
<li id="foo-1-3">Foo 1.3</li>
</ol>
</li>
<li id="foo-2"> Foo 2</li>
<li id="foo-3"> Foo 3</li>
</ol>
</div>
<div id="bar">
<h2>Bar</h2>
</div>
<div id="baz">
<h2>Baz</h2>
</div>
Then please run the code snippet (preferably on full page) and try:
Click on “Foo 1.1” (or “Foo 1.2” or “Foo 1.3”), wait 3 seconds and then click on “Foo”. As you can see, the background color animation of “Foo” ends at the same time as the background color animation of “Foo 1.1” (or “Foo 1.2” or “Foo 1.3”). One could also say that the CSS class “highlight” is removed from “Foo” too early.
Furthermore, if you initially click on “Foo 1.1” (or “Foo 1.2” or “Foo 1.3”), the list style item of “Foo” is highlighted as expected (and intended). But if you click on “Foo 1.1” (or “Foo 1.2” or “Foo 1.3”) again within 5 seconds, the list style item of “Foo” is not highlighted again. Only after waiting 5 seconds at least and then clicking on “Foo 1.1” (or “Foo 1.2” or “Foo 1.3”) again, the list style item of “Foo” is highlighted again.
This strange behaviour may be due to the pseudo-element ::before
. So it is about ol > li:has(.highlight)::before
. stopPropagation()
doesn’t seem to affect pseudo-elements because they are not part of the actual DOM.
Any idea how to fix this?