I have a clock widget on my website and I want the element to have my custom :target animation as soon as it's activated, without changing the hash.
I know, I could just write my code so the :target animation is played on the element when the widget is shown but I want to manipulate the element to have the :target pseudo-class.
Basically, I want the same effect as using a hash in the URL but without a URL change.
The Firefox DevTools are also based on HTML and JS, right? How do they do it?
Here's my animation in a snippet:
function initialize() {
// Here should the code be that applies the :target pseudo-class to div#uhr...
}
document.addEventListener('DOMContentLoaded', initialize)
/* My :target animation */
:target {
animation-name: hervorhebungWegenHash;
animation-duration: 10s;
animation-timing-function: linear;
animation-fill-mode: both;
}
@keyframes hervorhebungWegenHash {
2% {
color: black;
background-color: orange;
}
}
<iframe style="position:fixed;top:0px;left:0px;width:120px;height:120px;border:1px solid #4682b4;border-radius:50%;pointer-events:none;overflow:hidden;" id="uhr" src="https://www.lampe2020.de/widgets/uhr"> </iframe>
<a href="https://stackoverflow.com/a/46262124/17865928" title="copied 2022-05-26" style="position:absolute;top:125px">This clock widget is also from SO.</a>
To see the animation applied, go to my website, type "uhr" into the page (no textarea, just on the page). Otherwise you can check it by applying #page to my main page. Then the whole block in the middle should be orange and fade out to blue over the course of ~9 seconds.
Update: I've found a workaround but one question remains, out of interest:
How do the DevTools do it?
I have eventually found a workaround (not a solution but okay...) myself:
function mimicURLHash(hash) {
if (window.location.hash === '#' + hash) { // If the hash is also in the URL, remove it.
if (history.replaceState) {
history.replaceState("", document.title, window.location.pathname + window.location.search);
} else {
window.location.hash = '';
}
}
window.scroll(document.getElementById(hash).getBoundingClientRect().top, document.getElementById(hash).getBoundingClientRect().left);
document.getElementById(hash).classList.add('target');
}
You can see it applied here:
With this I just need to copy the CSS from the :target {} to the .target {} part. And then the function will be able to mimic a URL hash.
function mimicURLHash(hash) {
if (window.location.hash === '#' + hash) { // If the hash is also in the URL, remove it.
if (history.replaceState) {
history.replaceState("", document.title, window.location.pathname + window.location.search);
} else {
window.location.hash = '';
}
}
window.scroll(document.getElementById(hash).getBoundingClientRect().top, document.getElementById(hash).getBoundingClientRect().left);
document.getElementById(hash).classList.add('target');
}
function initialize() {
mimicURLHash('uhr'); // Normally you would feed window.location.hash to it or put it into a click event handler.
}
document.addEventListener('DOMContentLoaded', initialize)
/* My :target animation */
/* // The old CSS, no longer needed for this snippet:
:target {
animation-name: hervorhebungWegenHash;
animation-duration: 10s;
animation-timing-function: linear;
animation-fill-mode: both;
}*/
/* This is the CSS we need for this function to work: */
.target {
animation-name: hervorhebungWegenHash;
animation-duration: 10s;
animation-timing-function: linear;
animation-fill-mode: both;
}
@keyframes hervorhebungWegenHash {
2% {
color: black;
background-color: orange;
}
}
<iframe style="position:fixed;top:0px;left:0px;width:120px;height:120px;border:1px solid #4682b4;border-radius:50%;pointer-events:none;overflow:hidden;" id="uhr" src="https://www.lampe2020.de/widgets/uhr"> </iframe>
<a href="https://stackoverflow.com/a/46262124/17865928" title="copied 2022-05-26" style="position:absolute;top:125px">This clock widget is also from SO.</a>