On this site, I’ve added an animation (essentially, a link underline) that meant I needed to modify the Fancybox function. The new animation I mentioned above has an annoying artefact where it also applies on images where the fancybox
class exists.
This is not surprising, as the fancybox
attribute adds a a href
to all img
tags. Based on this, it is necessary to add a noanimate
class so that the link animation is not being applied. However, this isn’t such a simple affair. Due to the Lazy Load feature that NodeBB leverages, the images aren’t in the DOM until that specific chunk of data is loaded as the user scrolls through the post. To allow for this, we need to fire an event that selects each target image extension and then appends the existing classes with noanimate
as desired. For this to work, we have to create a duplicate each
function that uses the preexisting hook of action: posts.loaded
.
In usual cases of an entire page load, this could be quite greedy and have a significant impact on CPU cycles. Thankfully, the cost is in fact negated by the limited amount of data being pulled in each Ajax request using the post loaded feature.
Below is the code I developed for that
if (top.location.pathname !== '/login') {
$(window).on('action:posts.loaded', function(data) {
console.log("Loaded");
$(document).ready(function() {
$('a').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() {
$('a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]').addClass("noanimate");
});
});
});
}
if (top.location.pathname !== '/login') {
$(document).ready(function() {
$(window).on('action:ajaxify.end', function(data) {
this.$('a').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() {
$('a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]').addClass("noanimate");
data.preventDefault()
// Strip out the images contained inside blockquotes as this looks nasty :)
$('blockquote img').remove();
});
Fancybox.bind(
'a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]', {
groupAll: true,
}
);
});
});
}
The specific CSS that defines the animated underline (which you can see for example by hovering over the usernames in each thread) is shown below - note how we exempt noanimate
using the :not()
class. Basically, apply this css to all a href
except those that carry the appended class noanimate
.
It’s a bit of a bulldozer to break an egg, but it’s still efficient nonetheless.
.content p a {
position:relative;
}
.content p a:not(.noanimate):after {
background: none repeat scroll 0 0 transparent;
bottom: 0;
content: "";
display: block;
height: 1px;
left: 0%;
position: absolute;
background: var(--link);
transition: width 0.3s ease 0s, left 0.3s ease 0s;
width: 0;
}
.content p a:hover:after {
width: 100%;
left: 0;
}