85

Scroll event is not firing while scrolling the ul. I'm using jQuery version 1.10.2. As I'm loading the ul from an ajax page, I couldn't use $('ulId').on('scroll', function() {}); or other live methods. Please help me to find a solution.

$(document).on( 'scroll', '#ulId', function(){
    console.log('Event Fired');
});
Jawa
  • 2,336
  • 6
  • 34
  • 39
ABHILASH SB
  • 2,122
  • 2
  • 21
  • 31

8 Answers8

93

You probably forgot to give # before id for id selector, you need to give # before id ie is ulId

You probably need to bind the scroll event on the div that contains the ul and scrolls. You need to bind the event with div instead of `ul`
$(document).on( 'scroll', '#idOfDivThatContainsULandScroll', function(){
    console.log('Event Fired');
});

Edit

The above would not work because the scroll event does not bubble up in DOM which is used for event delegation, see this question why doesn't delegate work for scrolling.

But with modern browsers > IE 8, you can do it in another way. Instead of delegating by using jquery, you can do it using event capturing with javascript document.addEventListener, with the third argument as true; see how bubbling and capturing work in this tuturial.

Live Demo

document.addEventListener('scroll', function (event) {
    if (event.target.id === 'idOfUl') { // or any other filtering condition        
        console.log('scrolling', event.target);
    }
}, true /*Capture event*/);

If you do not need event delegation then you can bind scroll event directly to the ul instead of delegating it through document.

Live Demo

$("#idOfUl").on( 'scroll', function(){
   console.log('Event Fired');
});
derloopkat
  • 6,232
  • 16
  • 38
  • 45
Adil
  • 146,340
  • 25
  • 209
  • 204
  • 2
    If that is the case, why not `$('#ulId').on('scroll',function(){ console.log('Event Fired'); })` – IIIOXIII Oct 15 '13 at 07:38
  • 1
    @IIIOXIII In the question he states he cannot use `$('ulId').on('scroll', function() {});` because the UL is loaded from Ajax – Nunners Oct 15 '13 at 07:40
  • You problably need to bind scroll event on div that contains the ul bind the event with div instead of ul – Adil Oct 15 '13 at 07:46
  • @Adil As suggested in my updated answer, I agree, bind the scroll event to an outter div which is either hidden or of no size prior to loading the inner html with ajax. Then just display the outter div on load. – IIIOXIII Oct 15 '13 at 07:49
  • I told you why we need event delegation for your first comment – Adil Oct 15 '13 at 07:51
  • @ABHILASHSB: I'm encountering a similar problem. What exactly solved the problem for you? In my case, directly binding a scroll event to the element (after it's loaded) works, but an on() on a higher element that definitely has the correct selector the existing element never seems to fire. This is true even if I call on after the element is added. – zem May 24 '14 at 00:24
  • 12
    The answer to my problem is that scroll is not an event that bubbles, so it won't work properly with on(), which is mentioned in jquery's documentation for on(). – zem May 24 '14 at 00:57
25

Binding the scroll event after the ul has loaded using ajax has solved the issue. In my findings $(document).on( 'scroll', '#id', function () {...}) is not working and binding the scroll event after the ajax load found working.

$("#ulId").bind('scroll', function() {
   console.log('Event worked');
}); 

You may unbind the event after removing or replacing the ul.

Hope it may help someone.

ABHILASH SB
  • 2,122
  • 2
  • 21
  • 31
  • how to bind dynamically, during runtime? – Vipin Verma Jan 29 '16 at 03:57
  • 2
    https://stackoverflow.com/a/29051385/470749 seems to agree with you, although I'm disappointed because I thought the entire point of using `.on('scroll...` instead of `.scroll(...` was to catch dynamic changes to the DOM. – Ryan Oct 01 '17 at 18:36
  • From other sources, this doesn't work because apparently the scroll event does not bubble up. This prevents the on('scroll', selector, function) version from working since it relies on events bubbling up. – David Bradley Mar 19 '19 at 14:06
  • .bind is deprecated from jQuery 3.0.0 – Arosha Jun 21 '19 at 01:24
22

Using VueJS I tried every method in this question but none worked. So in case somebody is struggling whit the same:

mounted() {
  $(document).ready(function() { //<<====== wont work without this
      $(window).scroll(function() {
          console.log('logging');
      });
  });
},
animaonline
  • 3,715
  • 5
  • 30
  • 57
juliangonzalez
  • 4,231
  • 2
  • 37
  • 47
4

Another option could be:

$("#ulId").scroll(function () { console.log("Event Fired"); })

Reference: Here

MatayoshiMariano
  • 2,026
  • 19
  • 23
2
$("body").on("custom-scroll", ".myDiv", function(){
    console.log("Scrolled :P");
})

$("#btn").on("click", function(){
    $("body").append('<div class="myDiv"><br><br><p>Content1<p><br><br><p>Content2<p><br><br></div>');
    listenForScrollEvent($(".myDiv"));
});


function listenForScrollEvent(el){
    el.on("scroll", function(){
        el.trigger("custom-scroll");
    })
}

see this post - Bind scroll Event To Dynamic DIV?

Community
  • 1
  • 1
Vipin Verma
  • 5,330
  • 11
  • 50
  • 92
1

I know that this is quite old thing, but I solved issue like that: I had parent and child element was scrollable.

   if ($('#parent > *').length == 0 ){
        var wait = setInterval(function() {
            if($('#parent > *').length != 0 ) {
                $('#parent .child').bind('scroll',function() {
                  //do staff
                });
                clearInterval(wait);
            },1000);
        }

The issue I had is that I didn't know when the child is loaded to DOM, but I kept checking for it every second.

NOTE:this is useful if it happens soon but not right after document load, otherwise it will use clients computing power for no reason.

Riiwo
  • 1,839
  • 3
  • 15
  • 18
0

Can you place the #ulId in the document prior to the ajax load (with css display: none;), or wrap it in a containing div (with css display: none;), then just load the inner html during ajax page load, that way the scroll event will be linked to the div that is already there prior to the ajax?

Then you can use:

$('#ulId').on('scroll',function(){ console.log('Event Fired'); })

obviously replacing ulId with whatever the actual id of the scrollable div is.

Then set css display: block; on the #ulId (or containing div) upon load?

IIIOXIII
  • 980
  • 3
  • 15
  • 30
0

I just solved the problem with the fact that the scrollable element won't appear immediately after page load:

$(document).ready(function () {
   var checkIt = setInterval(function (){
       if($('body').find('.scrollable-wrapper').length > 0){
           clearInterval(checkIt);
           jQuery('.scrollable-wrapper').on('scroll', function () {
               console.log(1)
           });
       }
   },100)
});

After finding that the element is there, the interval will stop and the event will be fired to listen.

Amir2mi
  • 896
  • 9
  • 13