Giter Club home page Giter Club logo

Comments (9)

daun avatar daun commented on June 2, 2024 1

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.

daun avatar daun commented on June 2, 2024

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.

hirasso avatar hirasso commented on June 2, 2024

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.

hirasso avatar hirasso commented on June 2, 2024

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.

daun avatar daun commented on June 2, 2024

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.

daun avatar daun commented on June 2, 2024

Interestingly, event.stopPropagation() wouldn't help here, but that's as clean as it gets I reckon.

from preload-plugin.

hirasso avatar hirasso commented on June 2, 2024

Did you try the same check with the original listener, namely mouseover and capture: false?

from preload-plugin.

daun avatar daun commented on June 2, 2024

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.

hirasso avatar hirasso commented on June 2, 2024

Nice! Let's switch to mouseenter then. I just asked out of curiosity :)

from preload-plugin.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.