Comments (9)
So this seems to do the trick when using mouseenter
:
swup.delegatedListeners.mouseenter = delegate(
document.body,
swup.options.linkSelector,
'mouseenter',
this.onMouseEnter.bind(this),
{ capture: true }
);
onMouseEnter = (event) => {
if (event.target !== event.delegateTarget) {
return;
}
// Return early on devices that don't support hover
if (!this.deviceSupportsHover()) return;
this.swup.triggerEvent('hoverLink', event);
this.preloadLink(event.delegateTarget);
};
from preload-plugin.
That's a bit surprising. Doesn't that also mean that swup's normal click
handler will fire multiple times in similar cases of a span nested inside a div? I assumed the delegate library would handle that by just passing the actual element as delegateTarget
...
from preload-plugin.
It was suprising to me, too. Turns out my description is a bit wrong, MDN has a better one. It's not due to bubbling, but due to the fact that mouseover
fires for the link itself as well as for all children of the link if the mouse moves over them.
I quickly hacked something together that reduces the fired event to 1
for each hover (tested):
onMouseOver = (event) => {
const target = event.delegateTarget;
// Return early if the mouse already is on the link
if (target.hasAttribute('data-swup-mouse-over')) {
return;
}
// Set the data attribute
target.setAttribute('data-swup-mouse-over', '');
// Remove the data attribute on mouseleave
target.addEventListener(
'mouseleave',
() => {
target.removeAttribute('data-swup-mouse-over');
},
{ once: true }
);
// Will only fire once per mouseover
console.log('mouseOver');
this.swup.triggerEvent('hoverLink', event);
this.preloadLink(event.delegateTarget);
};
A bit nasty, I know... But the best I could come up with until now. Maybe you can find a better approach? Another alternative could be to augment the element itself (dummy code):
if (event.delegateTarget.__swupMouseOver) return;
// ...
from preload-plugin.
Actually, I was wrong again. The delegation of mouseenter
actually also works, if using the capture phase:
swup.delegatedListeners.mouseover = delegate(
document.body,
swup.options.linkSelector,
'mouseenter',
this.onMouseOver.bind(this),
{ capture: true } // << this!
);
...and the handler here is also fired multiple times for the children! 🤦♂️
Something weird with the delegation library maybe? Anyhow, the above code will also work in this scenario.
from preload-plugin.
For mouseenter, at least we could compare event.target
and event.delegateTarget
and ignore it if they aren't the same element, no? Not sure how that holds up for children that cover the link completely vs. children that don't.
from preload-plugin.
Interestingly, event.stopPropagation()
wouldn't help here, but that's as clean as it gets I reckon.
from preload-plugin.
Did you try the same check with the original listener, namely mouseover
and capture: false
?
from preload-plugin.
Yes, that fires twice, but that's to be expected from what I read. Once when entering the link, and once when returning from the inner span to the link. There's probably no way around that since the event targets always match.
Is there a reason not to go with the mouseenter
version above? I've read somewhere it's much better for performance as well since it triggers less often.
from preload-plugin.
Nice! Let's switch to mouseenter then. I just asked out of curiosity :)
from preload-plugin.
Related Issues (20)
- `options.preloadVisibleLinks.enabled` not being applied automatically HOT 1
- Links with identical `href` will remove urls from `preloadVisibleLinks` queue even if these should actually be preloaded. HOT 1
- Preload stylesheets
- `options.preloadHoveredLinks` incorrectly set up HOT 4
- [Bug]: External links are not being properly ignored on hover HOT 5
- Detect network idle time for preloading? HOT 8
- [Question] How to activate hover only preload HOT 2
- Prepare for new `shouldIgnoreVisit()` in swup@3
- Optimize the preload mechanism on desktop and mobile HOT 1
- Allow marking parent container to preload all children HOT 1
- Remove duplicated logic for handling fetch response HOT 1
- 'pagePreloaded' event doesn't pass any arguments HOT 2
- Priority queue
- Feature: preload links in viewport
- Feature: preload links on focus
- Possibility to ignore a certain link? HOT 1
- dist/index.module.js is missing HOT 2
- Bundling error with webpack
- requestIdleCallback not available in Safari HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from preload-plugin.