简体   繁体   中英

Re-initiating bxSlider for ajax-loaded content via jscroll

I am having content that spans over multiple pages. Via jscroll I can successfully append the further pages' content to my current page. I am using a button to initiate the loading of the additional content.

Throughout my pages I use multiple bxSlider carousels that stop working for the appended, AJAX-loaded content since bxSlider obviously gets fired (and needs to be, as the documentation states) on pageload, so it misses any new sliders in the AJAX-loaded content.

Now, bxSlider has a as a reloadSlider function, which though does not seem to recognise newly added sliders after initial page loading, it seems to be solely for adding new slides to existing sliders.

Is there a way to trigger bxSlider to re-evaluate the page's current content state and handle new sliders that get added when the button for jscroll is being clicked (possibly handling any delay that fetching the content creates)?

Here just a rough sketch of the constellation:

<div id="outer_wrapper">
    <div id="content_wrapper">
        <!-- My initial content -->
        <div id="somediv">...</div>
        <div id="somediv2">...</div>
        <div id="somediv3" class="author_slider">My first carousel</div>
        <div id="somediv4">...</div>
        <div id="somediv5">...</div>
        <a href="page2.php" class="loadcontent">Load more content</a>

        <!-- My AJAX-loaded second page, bxSlider fails -->
        <div id="somediv6">...</div>
        <div id="somediv7">...</div>
        <div id="somediv8" class="author_slider">My second carousel</div>
        <div id="somediv9">...</div>
        <div id="somediv10">...</div>
        <a href="page3.php" class="loadcontent">Load more content</a>
    </div>
</div>

Edit: This is my JS for bxSlider and jscroll:

// Slider — Widget Authors
jQuery(document).ready(function(jQuery) {
    jQuery('.author_slider ul').bxSlider({
        minSlides: 3,
        maxSlides: 5,
        slideWidth: 104,
        speed: 500,
        pager: true,
        nextSelector: '.nextLink',
        prevSelector: '.prevLink'
    });
});


// JScroll
jQuery(document).ready(function(jQuery) {
    jQuery('#content_wrapper').jscroll({
        loadingHtml: '<div class="loadcontent loading"><a>Loading …</a></div>',
        nextSelector: '.loadcontent',
        contentSelector: '#content_wrapper',
        autoTrigger: false
    });
});

After you load your dynamic HTML that holds the new sliders, you must call bxSlider on those elements before you can access them as slider. Since the initial $('.author_slider ul').bxSlider() call has already been executed on page load (before your dynamic content), the new carousels missed that and therefore are not initialized as bxSliders.

Re-initializing the same sliders is a waste and can cause problems, so you need to keep track of which sliders you are initializing so you don't do it twice.

The other thing to watch out for on the bxSlider() initialization is using selectors for your paging mechanisms that are too general. They need to be specific to the slider you are initializing or the results will be unpredictable or...bad.

because the controls (pager and prev/next) elements are outside of the slider itself, you are providing selectors to specify which element to use for this purpose. So, before we can initialize the slider, we need to identify and be able to 'select' the corresponding control elements. Given you code, there is no inherent way to select these without modification, so that is the first step - find the control elements and put an identifier on them.

Then, you can initialize the new slider and pass these new selectors that uniquely identify the control elements you want.

Thus, if you load this content for example:

    <!-- My AJAX-loaded second page, bxSlider fails -->
            <div id="somediv6">...</div>
            <div id="somediv7">...</div>
            <div id="somediv8" class="author_slider">
              My second carousel
            </div>

Pass in a function like the one below to the jScroll 'callback' parameter when you initialize it. Also, use it for your first initialization as well (don't call jQuery('.author_slider ul').bxSlider() directly - instead call the function below when the page is done loading.

 <script>





var trackSliders = [];
// use this to increment the id count...
var trackSliderCount = 0;

var initSliders = function() {

    // this re-initialized ALL sliders, but that might be okay?
    jQuery('.author_slider ul').each( function( index, item ) {

        /* can't use the id attribute, so lets add our
        own data attribute */
        var obj = jQuery(item);
        // make sure to use lowercase in your data attribute name
        var id = obj.data('carousel-id');
        if (trackSliders.indexOf( id ) == -1 )
        {  

            var id = trackSliderCount++

            // this item has NOT been initialized.
            // save the id so we don't re-initialize
            obj.data('carousel-id', id);
            // push the id to our slider tracking array
            trackSliders.push( obj.data('carousel-id') );

            /* find control elements...

               first step here is to get the closest containing
               parent element that is identified
               by the class 'author_slider'
             */
             var container = jQuery(obj.closest('.author_slider'));

             // now, get the child elements from the container 
             // that have your control elements
             var prev = jQuery(container.find('.prevLink'));
             var next = jQuery(container.find('.nextLink'));
             var pager = jQuery(container.find('.author_pager'));

             // now, we need to modify these elements so we can
             // select them uniquely.  If I just wanted to store
             // values, I would use the jQuery().data(key, val),
             // but that won't work when we use it for selection
             // ( that is for a different lesson ).  Instead, 
             // let's just assign id's to these elements and use 
             // ids.  Append 'id' from above to make them unique
             var prevId = 'bxPrev_' + id;
             var nextId = 'bxNext_' + id;
             var pagerId = 'bxPager_' + id;

             // now, set the id attribute on each object.
             prev.attr('id', prevId );
             next.attr('id', nextId );
             pager.attr('id', pagerId );


            // now we can call bxSlider, but use our new id's 
            // as selectors.
            obj.bxSlider({
                minSlides: 3,
                maxSlides: 5,
                slideWidth: 104,
                speed: 500,
                pager: true,
                nextSelector: '#' + nextId,
                prevSelector: '#' + prevId,
                pagerSelector: '#' + pagerId,
                prevText: '<i class="car2go-icon-caret-left"></i>',
                nextText: '<i class="car2go-icon-caret-right"></i>',
            });
        };
    });
};


// jScroll

jQuery(document).ready(function(jQuery) {
    // invoke the method
    initSliders();

    jQuery('.post_list_posts').jscroll({
        loadingHtml: '<div class="link_nextposts loading"><a><i class="car2go-icon-load"></i>Loading …</a></div>',
        nextSelector: '.link_nextposts a',
        contentSelector: '.post_list_posts',
        autoTrigger: false,
        // pass in the method to the callback.
        callback: initSliders
    });
});
</script>

the new data-attribute stuff is not tested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM