Vaadin 13: How to listen for scroll events

Hi,

to fade in some elements on scroll I want to listen for scroll-events.
I thought it is as easy as

getElement().addEventListener("scroll", e -> {
			// do the magic
		});

but sadly this method will never be executed. The listener works when I listen for “click”-events.

Can anybody tell me what I have to do to make it work?

Best regards,
Torsten

https://www.w3schools.com/jsref/event_onscroll.asp says “The onscroll event occurs when an element’s scrollbar is being scrolled.”

So say you have Div div and use div.getElement(), does the div have scrollbar?

Hi,

yes, there is a scrollbar and I scrolled it down ;-).

I just moved to Vaadin 14 and reduced the sample app to the max.
The listener is bound to every available element, but never called.

@Route("")
@Theme(value = Lumo.class, variant = Lumo.LIGHT)
public class OverView extends Div
{
	public OverView()
	{
		getStyle().set("background-color", "#009EE2");
		setHeight("9000px");
		
		DomEventListener l = e -> System.out.println("invoked!");

		Div div = new Div();
		add(div);
		div.getElement().addEventListener("scroll", l);
		getElement().addEventListener("scroll", l);
		UI.getCurrent().getElement().addEventListener("scroll", l);
	}
}

How to practically use it?

I am trying to add scroll event to a div, in which I need to change images.

Can you plase elaborate this more practically ?

Very strange :frowning:

I just tested the same above code with another event and it worked

	DomEventListener l = e -> System.out.println("invoked!");

	Div div = new Div();
	add(div);
	div.getElement().addEventListener("mouseleave", l);
	getElement().addEventListener("mouseleave", l);
	UI.getCurrent().getElement().addEventListener("mouseleave", l);

2019-10-10 13:13:37.703 INFO 1181 — [ webpack]
dev-webpack : e[38;5;35mWatchdog connected.e[0m

invoked!
invoked!
invoked!

However, when I use this

	DomEventListener l = e -> System.out.println("invoked!");

	Div div = new Div();
	add(div);
	div.getElement().addEventListener("scroll", l);
	getElement().addEventListener("scroll", l);
	UI.getCurrent().getElement().addEventListener("scroll", l);

No output on console

2019-10-10 13:14:43.002 INFO 1181 — [ webpack]
dev-webpack : e[38;5;35mWatchdog connected.e[0m

More update on this, I can see the ‘Scroll’ event got loaded from ‘Inspect’

What can be the reason it doesn’t work?

17884625.png

More update on this, I can see the ‘Scroll’ event got loaded from ‘Inspect’

Which element you have used to attach the scroll listener in the console ?

Denis Anisimov:

More update on this, I can see the ‘Scroll’ event got loaded from ‘Inspect’

Which element you have used to attach the scroll listener in the console ?

div.getElement().addEventListener(“scroll”, l);

I suppose you mean this. So am using div element.

If not, if you can elaborate please!

No, I meant your message:

More update on this, I can see the ‘Scroll’ event got loaded from ‘Inspect’

I’ve understood it as : you had added a listener in the console and you can see that event is fired inside the listener.
So it works if you add a JS listener in the console, right ?
Which element you had used to add a listener ?

div.getElement().addEventListener(“scroll”, l);

This is a Java code which doesn’t work for you.

Denis Anisimov:
No, I meant your message:

More update on this, I can see the ‘Scroll’ event got loaded from ‘Inspect’

I’ve understood it as : you had added a listener in the console and you can see that event is fired inside the listener.
So it works if you add a JS listener in the console, right ?
Which element you had used to add a listener ?

ok. No, I have not added any element from console. I just found the listener by inspect element and then from the chrome inspect i saw a tab ‘Event Listener’ which have the value ‘scroll’
Once I remove the java code, the value also gets removed. So, in my understanding it is controlled from Java code.

However, the event handling doesn’t work.

Got it.

Using a console I’ve added a scroll listener to a div element :

div.addEventListener('scroll', function(){ console.error("event");});

It doesn’t work.
Apparently it’s not supported on the client side (JS) at all.
That’s why it doesn’t work when you are using Flow as well.

Using a console I’ve added a scroll listener to the window object:

window.addEventListener('scroll', function(){ console.error("oooo");});

It works.

https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event

Denis Anisimov:
Got it.

Using a console I’ve added a scroll listener to a div element :

div.addEventListener('scroll', function(){ console.error("event");});

It doesn’t work.
Apparently it’s not supported on the client side (JS) at all.
That’s why it doesn’t work when you are using Flow as well.

Using a console I’ve added a scroll listener to the window object:

window.addEventListener('scroll', function(){ console.error("oooo");});

It works.

Thank you for the input Denis. However, I would still like to have the event handler to work for the java code.
Since, I need to add the scroll event to div. I cannot use a window object inside java code to have the scroll working.

div.getElement().addEventListener(“scroll”, l);

strange thing is this works for mouseleave and other events, why not for ‘Scroll’ ?

Can you advise please ?

strange thing is this works for mouseleave and other events, why not for ‘Scroll’ ?

It doesn’t work because it doesn’t work in JS in this way.
I don’t know why it doesn’t work in JS unfortunately. I’m not a JS expert.

You may call any JS from Java side.

UI.getCurrent().getPage().executeJS("window.addEventListener('scroll', function(){ console.error('oooo');});");

Anticipating your following question “how to call a Java side from the client side listener” you may add a @ClientCallable method to your component and then you may use inside the client side function this.$server.callServerSide().