Search code examples
jqueryscrollspy

Jquery ScrollSpy - works in the example file - doesn't work when I do it


I'm using the following script which allows you to detect when elements enter and leave your viewpoint: https://github.com/thesmart/jquery-scrollspy

The example the author provides works great and here's the code for it:

This part basically creates all the elements on the screen:

var body = $('body');
for (var i = 0; i < 100; ++i) {
    var element = $('<div id="tile-' + i + '" class="tile"><h2>Tile #' + i + '</h2></div>');
    body.append(element);
}

This is the style for all the elements:

.tile {
    width: 290px;
    height: 290px;
    float: left;
    border: 1px solid #999;
    margin: 4px;
}

And this is the ScrollSpy script that checks when elements enter and leave the viewpoint:

$('.tile').on('scrollSpy:enter', function() {
    console.log('enter:', $(this).attr('id'));
});

$('.tile').on('scrollSpy:exit', function() {
    console.log('exit:', $(this).attr('id'));
});

$('.tile').scrollSpy();

So far, so good, everything in the example file works. Now what I've tried to do is to manually enter my own element:

<div id="tile-220" class="tile"><h2>Tile #220</h2></div>

And then use the same ScrollSpy code but updated to see if I can get the same result:

$('#tile-220').on('scrollSpy:enter', function() {
    alert("test");
});

$('#tile-220').on('scrollSpy:exit', function() {
    alert("test2");
});

$('#tile-220').scrollSpy();

This for some reason, doesn't work. Now if I used instead of #tile-220 one that's generated with the first script, such as #tile-90, it works great, just not with an ID that I added manually. Can anyone help me figure out what I'm missing please?

Thank you very much in advance!


Solution

  • It works for manually added tiles as well.

    All you need to do is add those in correct position.

    Here is the code (snippet):

    <body>
    <script> //Script 1
        var body = $('body');
        for (var i = 0; i < 100; ++i) {
            var element = $('<div id="tile-' + i + '" class="tile"><h2>Tile #' + i + '</h2></div>');
            body.append(element);
        }
    </script>
    <style>
        .tile {
            width: 290px;
            height: 290px;
            float: left;
            border: 1px solid #999;
            margin: 4px;
        }
    </style>
    
    <div id="tile-221" class="tile"><h2>Tile #221</h2></div>
    <div id="tile-222" class="tile"><h2>Tile #222</h2></div>
    <div id="tile-223" class="tile"><h2>Tile #223</h2></div>
    
    <script> //Script 2
        $('.tile').on('scrollSpy:enter', function() {
            console.log('enter:', $(this).attr('id'));
        });
    
        $('.tile').on('scrollSpy:exit', function() {
            console.log('exit:', $(this).attr('id'));
        });
    
        $('.tile').scrollSpy();
    </script>
    </body>
    

    It wont work if you add those new divs after Script 2, because as the page loads, script 2 executes for all the divs (tiles) which have been loaded.

    So put your divs before script 2.

    OR you can load the script 2 after all the divs on page has been loaded :

    <script>
    $(function(){ //Addition
        $('.tile').on('scrollSpy:enter', function() {
            console.log('enter:', $(this).attr('id'));
        });
    
        $('.tile').on('scrollSpy:exit', function() {
            console.log('exit:', $(this).attr('id'));
        });
    
        $('.tile').scrollSpy();
        });
    </script>
    

    Now you can put your new divs anywhere.