destroy iDangerous Swiper if window is resized to

2020-07-03 04:58发布

问题:

i'm using iDangerous Swiper for my website in lower resolutions. here is how i'm calling it:

var resolution = 670;
if ($(window).width() < resolution) {
var mySwiper = $('.swiper-container').swiper({
    mode:'horizontal',
    loop: true,
    grabCursor: true,
    paginationClickable: true
});

so, when you access it in a desktop browser, the swiper will not be called. what i want to do is to "turn it on" if the user resizes the window to a size smaller than resolution or destroy it if the user accesses it in a small window size and then resizes it to bigger than resolution. i tried this, but it didn't work:

$(window).resize(function(){
    if ($(window).width() < resolution) {
        if(typeof(mySwiper) === "undefined" ) {
            var mySwiper = $('.swiper-container').swiper({
                mode:'horizontal',
                loop: true,
                grabCursor: true,
                paginationClickable: true
            });
        }
    } else {
        if (typeof(mySwiper) !== "undefined" ) {
            mySwiper.destroy();
        }
    }
});

two undesirable things happen:

  1. if the user is in a small resolution and resizes it to a resolution that still calls the swiper, it restarts the swiper.
  2. if the user is in a small resolution and resizes it to a bigger resolution, it is not destroyed.

i thing my problem is the typeof. i don't know much how variables work when they are called like this: $('.swiper-container').swiper().

how do i "uncall" swiper and how not call it if it was already called?

回答1:

My solution:

var mySwiper = undefined;
function initSwiper() {
    var screenWidth = $(window).width();
    if(screenWidth < 992 && mySwiper == undefined) {            
        mySwiper = new Swiper('.swiper-container', {            
            spaceBetween: 0,
            freeMode: true
        });
    } else if (screenWidth > 991 && mySwiper != undefined) {
        mySwiper.destroy();
        mySwiper = undefined;
        jQuery('.swiper-wrapper').removeAttr('style');
        jQuery('.swiper-slide').removeAttr('style');            
    }        
}

//Swiper plugin initialization
initSwiper();

//Swiper plugin initialization on window resize
$(window).on('resize', function(){
    initSwiper();        
});

And it worx! :)



回答2:

I was having the same problem and found that as soon as the width was beyond my max width, mySwiper was again undefined and therefore the if(typeof) statement always returned false.

I found another hybrid solution with the fired[] array below and also realized that while the destroy() method may be executing in my example, the swiper itself had added a style attribute to the wrapper and slide DIVs which was persisting after the destroy method was called and only went away with a page refresh. After I added the removeAttr() method calls on the two DIVs, everything worked as expected.

Your mileage may vary.

$(window).on('resize', function ()
{
    if ($(this).width() <= 383 && !fired[0])
    {
        fired[0] = true;
        fired[1] = false;

        mySwiper = $('.swiper-container').swiper({ mode: 'horizontal', loop: false, wrapperClass: 'swiper-wrapper', slideClass: 'swiper-slide' });
    }
    else if ($(this).width() >= 384 && !fired[1])
    {
        fired[0] = false;
        fired[1] = true;

        mySwiper.destroy();

        $('.swiper-wrapper').removeAttr('style');
        $('.swiper-slide').removeAttr('style');
    }
});


回答3:

I had the same problem and took a similar solution:

init function:

var mySwiper;

my resize function:

if(jQuery(window).width() < 672) {
    if (typeof mySwiper == 'undefined') {
        mySwiper = new Swiper('#myId', {
            calculateHeight: true
        });
    }
} else {
    if (typeof mySwiper != 'undefined') {
        // destroy and delete swiper object
        mySwiper.destroy();
        mySwiper = undefined;

        // reset styling for wrapper and slides
        jQuery('.swiper-wrapper').removeAttr('style');
        jQuery('.swiper-slide').removeAttr('style');
    }
}


回答4:

For anyone still having problems destroying and initialising Swiper on demand try calling reInit() with a slight delay.

define Swiper reference on page load

var mySwiper;

Start Swiper

// Set Slider 
        mySwiper = new Swiper ('.swiper-container', {loop: true }); 
 // Run Update after 500ms
        setTimeout(function() { mySwiper.reInit(); },500);    

Destory Swiper

  if (typeof mySwiper != 'undefined') {  
    mySwiper.destroy();
    mySwiper = undefined;
  }      

If your updating markup through ajax ensure you empty the container first. i.e:

 if (typeof mySwiper != 'undefined') {  
   mySwiper.destroy();
   mySwiper = undefined;
 }    
 $('#container-with-swiper-markup').html("");


回答5:

Okay, so I know I'm late to the party, but I had similar issues and ended up with a solution that works solid.

The story: Swiper needs to run on desktop, but not on mobile (small screens) and should be able to change between them on resize.

Requirements: In my example, I'm using jQuery, Swiper and Modernizr (for media queries, as window width etc is unreliable).

JavaScript:

/*! Michael Pumo - Web Development. http://michaelpumo.com */

(function($, Modernizr) {

    'use strict';

    var state = {

        swiper: false,

        setOrGetDevice: function(device) {

            if (typeof(device) === 'undefined') {
                var mq = Modernizr.mq('only screen and (min-width: 768px)') ? 'desktop' : 'mobile';
                device = mq;
            }

            return device;

        },

        device: function() {

            return state.setOrGetDevice();

        }

    };

    var cache = {

        $window: $(window),
        $swiper: $('.swiper-container'),
        $swiperElements: $('.swiper-container, .swiper-wrapper, .swiper-slide')

    };

    var swiper;

    var app = {

        init: function() {

            app.swiper();

        },

        swiper: function() {

            if(state.device() === 'desktop' && !state.swiper) {

                swiper = cache.$swiper.swiper({
                    parallax: false,
                    initialSlide: 0,
                    direction: 'horizontal',
                    loop: true,
                    autoplay: 3000,
                    speed: 1000
                });

                state.swiper = true;

            } else if(state.device() === 'mobile' && state.swiper) {

                swiper.destroy();
                swiper = undefined;
                cache.$swiperElements.removeAttr('style');

                state.swiper = false;

            }

        }

    };

    $(function() {
        app.init();
    });

    cache.$window.on('resize', function() {

        var mq = Modernizr.mq('only screen and (min-width: 768px)') ? 'desktop' : 'mobile';
        state.setOrGetDevice(mq);
        app.init();

    });

})(window.jQuery, window.Modernizr);

As well as checking the 'device' (in other words, mobile size or desktop size), it checks against a flag I set in state.swiper. As this is a mobile-first approach, this flag is initially set to false.

I know that my explanation is brief, but this works 100% and has the benefit of not initializing Swiper at every stage of the resize, thanks to the flag.

The HTML would just be the standard HTML that Swiper requires, so that's what you should use if you're going with this solution.

Hope it can be of some help to someone.

Thanks, Mikey.



回答6:

I have a better solution which has given by the http://idangero.us


var mySwiper = new Swiper('.swiper-container', {
    // Optional parameters
    direction: 'vertical',
    loop: true
})
if (window.innerWidth > 767) {
    swiper.detachEvents();
}


标签: jquery swiper