2016-07-06 8 views
7

Sto provando a scrivere un plugin JQuery chiamato grid2carousel che prende del contenuto in una griglia in stile Bootstrap sui dispositivi desktop e diventa un carosello su schermi più piccoli.Plugin JQuery non funziona se utilizzato più volte in una pagina

Il plug-in funziona bene se è l'unica istanza di esso su una pagina ma presenta alcuni problemi se ce ne sono più di uno. Ho creato un Codepen qui per dimostrare il problema:

http://codepen.io/decodedcreative/pen/BzdBpb

Provare a commentare uno dei componenti della sezione HTML della codepen, il ridimensionamento del browser finchè non diventa una giostra, e poi ripetere di nuovo questo processo con esso non commentato

Il plugin funziona eseguendo una funzione interna denominata SetupPlugin ogni volta che la larghezza del browser è inferiore a un punto di interruzione specificato in un attributo di dati nell'HTML. Se la larghezza del browser supera questo punto di interruzione, una funzione chiamata DestroyPlugin ripristina lo stato originale del codice HTML. In questo modo:

 checkDeviceState = function(){ 
      if($(window).width()>breakpointValue){ 
       destroyPlugin(); 
      }else{ 
       if(!$element.hasClass('loaded')){ 
        setupPlugin(); 
       } 
      } 
     }, 

Di seguito è riportato il mio codice del plugin nella sua interezza. Qualcuno potrebbe darmi un puntatore su cosa sto facendo di sbagliato qui?

(function (window, $){ 
$.grid2Carousel = function (node, options){ 
    var 
    options = $.extend({slidesSelector: '.g2c-slides', buttonsSelector: '.g2c-controls .arrow'}, {},options), 
    $element = $(node), 
    elementHeight = 0, 
    $slides = $element.find(options.slidesSelector).children(), 
    $buttons = $element.find(options.buttonsSelector), 
    noOfItems = $element.children().length + 1, 
    breakpoint = $element.data("bp"), 
    breakpointValue = 0; 

    switch(breakpoint){ 
     case "sm": 
      breakpointValue = 767; 
      break; 
     case "md": 
      breakpointValue = 991; 
      break; 
     case "lg": 
      breakpointValue = 1199; 
      break; 
    } 

    setupPlugin = function(){ 

     // Add loaded CSS class to parent element which adds styles to turn grid layout into carousel layout 
     $element.addClass("loaded"); 

     // Get the height of the tallest child element 
     elementHeight = getTallestInCollection($slides) 

     // As the carousel slides are stacked on top of each other with absolute positioning, the carousel doesn't have a height. Set its height using JS to the height of the tallest item; 
     $element.height(elementHeight); 

     // Add active class to the first slide 
     $slides.first().addClass('active'); 


     $buttons.on("click", changeSlide); 

    }, 

    destroyPlugin = function(){ 
     $element.removeClass("loaded"); 
     $element.height("auto"); 
     $buttons.off("click"); 
     $slides.removeClass("active"); 
    }, 

    checkDeviceState = function(){ 
     if($(window).width()>breakpointValue){ 
      destroyPlugin(); 
     }else{ 
      if(!$element.hasClass('loaded')){ 
       setupPlugin(); 
      } 
     } 
    }, 

    changeSlide = function(){ 
     var $activeSlide = $slides.filter(".active"), 
      $nextActive = null, 
      prevSlideNo = $activeSlide.prev().index() + 1, 
      nextSlideNo = $activeSlide.next().index() + 1; 

     if($(this).hasClass('left')){ 


      if(prevSlideNo !== 0){ 
       $nextActive = $activeSlide.prev(); 
       $nextActive.addClass('active'); 
       $slides.filter(".active").not($nextActive).removeClass("active"); 
      }else{ 
       $nextActive = $slides.last(); 
       $nextActive.addClass('active'); 
       $slides.filter(".active").not($nextActive).removeClass("active"); 
      } 

     }else if($(this).hasClass('right')){ 


      if(nextSlideNo !== 0){ 
       $nextActive = $activeSlide.next(); 
       $nextActive.addClass('active'); 
       $slides.filter(".active").not($nextActive).removeClass("active"); 
      }else{ 
       $nextActive = $slides.first(); 
       $nextActive.addClass('active'); 
       $slides.filter(".active").not($nextActive).removeClass("active"); 
      } 

     } 
    }, 

    getTallestInCollection = function(collection){ 

     $(collection).each(function(){ 
      if($(this).outerHeight() > elementHeight){ 
       elementHeight = $(this).outerHeight(); 
      } 
     }); 

     return elementHeight; 

    }; 

    setupPlugin(); 
    checkDeviceState(); 
    $(window).on("resize", checkDeviceState); 

} 




$.fn.grid2Carousel = function (options) { 
    this.each(function (index, node) { 
     $.grid2Carousel(node, options) 
    }); 

    return this 
} 
})(window, jQuery); 

Molte grazie,

James

risposta

18

Si prega di verificare la linea # 30 nel codice del plugin, sembra che hai appena dimentica di aggiungere var parola chiave in modo, invece di creare variabili locali per memorizza le funzioni setupPlugin, destoryPlugin e così via hai creato variabili globali e poi ogni nuova inizializzazione del tuo plugin sta riscrivendo queste funzioni per puntare a un cursore appena creato.

setupPlugin = function(){ 

dovrebbe essere

var setupPlugin = function(){ 

codice aggiornato here.

+0

* facepalm. Grazie mille! –

Problemi correlati