2016-01-30 1 views
1

J'ai créé un plugin JQuery simple basé sur le modèle Boilerplate. Cela fonctionne bien sauf un problème. Lorsque j'applique mon plugin au second <div>, le premier cesse de fonctionner. De plus, tous les divs ont le même identifiant unique que je génère lors de la création d'une nouvelle instance. Comment restructurer le code existant pour encapsuler les variables et le faire fonctionner correctement? Le code ci-dessous est mon plugin:JQuery Boilerplate plugin utilise les mêmes variables internes pour la nouvelle instance

;(function($) { 

    var pluginName = "Pulsar", 
     dataKey = "plugin_" + pluginName, 
     defaults = { 
      key : "color", 
      from: "#000", 
      to: "#fff",   
      duration: 5   
     }; 

    var self = null; 
    var interval = null;  
    var flag = false; 
    var uniqueID = uniqueId(); 

    //PRIVATE FUNCTIONS 
    function Plugin(element, options) { 
     this.element = element; 
     this.options = $.extend({}, defaults, options) ; 
     this._defaults = defaults; 
     this._name = pluginName; 

     this.init();   
    } 

    function uniqueId() { 
     return 'id-' + Math.random().toString(36).substr(2, 16); 
    };  

    function Init(key, from, to, duration){ 
     $(self.element).css({ 
      WebkitTransition : 'all ease '+duration+'s', 
      MozTransition : 'all ease '+duration+'s', 
      MsTransition  : 'all ease '+duration+'s', 
      OTransition  : 'all ease '+duration+'s', 
      transition  : 'all ease '+duration+'s' 
     }); 
     $(self.element).text($(self.element).text()+' '+uniqueID); 

     var state1, state2; 

     state1 = '{ "'+key+'" : "'+from+'"}'; 
     state2 = '{ "'+key+'" : "'+to+'"}'; 

     var state1JSON = JSON.parse(state1); 
     var state2JSON = JSON.parse(state2); 

     $(self.element).css(state1JSON); 

     clearInterval(interval); 
     interval = setInterval(function(){ 
      if(!flag){ 
       $(self.element).css(state2JSON); 
       flag=true;     
      } 
      else{ 
       $(self.element).css(state1JSON); 
       flag=false;    
      }    
     }, duration * 1000); 
    } 

    //PUBLIC FUNCTIONS 
    Plugin.prototype = { 
     init: function(){ 
      self = this; 
      $(self.element).attr("pluginID", uniqueID);   
      Init(this.options.key, this.options.from, this.options.to, this.options.duration); 
     }, 
     update: function(key, from, to, duration){   
      Init(key, from, to, duration);   
     }, 
     getID: function(){ 
      return uniqueID; 
     } 
    }; 

    $.fn[pluginName] = function (options) { 
     var plugin = this.data(dataKey); 

     // has plugin instantiated ? 
     if (plugin instanceof Plugin) { 
      // if have options arguments, call plugin.init() again 
      if (typeof options !== 'undefined') { 
       plugin.init(options); 
      } 
     } else { 
      plugin = new Plugin(this, options); 
      this.data(dataKey, plugin); 
     } 

     return plugin; 
    }; 


})(jQuery); 

Comment ça marche vous pouvez voir sur jsfiddle

MISE À JOUR: Mon erreur a été la déclaration des variables à un mauvais endroit et leur utilisation de, ils ont été utilisés par tous instances et pas d'instance concrète. Merci à guest271314. Il m'a donné une idée de comment corriger mon problème. Le plug-in correct qui fonctionne comme un charme est ci-dessous:

;(function($) { 

var pluginName = "Pulsar", 
    dataKey = "plugin_" + pluginName, 
    defaults = { 
     key : "color", 
     from: "#000", 
     to: "#fff",   
     duration: 5,    
     onChange: function(){} 
    }; 


//PRIVATE FUNCTIONS 
function Plugin(element, options) { 
    this.element = element; 
    this.options = $.extend({}, defaults, options) ; 
    this._defaults = defaults; 
    this._name = pluginName; 

    //init all required variables 
    this.interval = null; 
    this.flag = false; 

    this.init(options);  
} 

function Init(self, key, from, to, duration){ 
    var element = self.element; 

    $(element).css({ 
     WebkitTransition : 'all '+duration+'s', 
     MozTransition : 'all '+duration+'s', 
     MsTransition  : 'all '+duration+'s', 
     OTransition  : 'all '+duration+'s', 
     transition  : 'all '+duration+'s' 
    });  

    var state1, state2; 

    state1 = '{ "'+key+'" : "'+from+'"}'; 
    state2 = '{ "'+key+'" : "'+to+'"}'; 

    var state1JSON = JSON.parse(state1); 
    var state2JSON = JSON.parse(state2); 

    $(element).css(state1JSON); 

    if(self.interval != null){   
     clearInterval(self.interval); 
    } 
    self.interval = setInterval(function(){ 
     if(!self.flag){ 
      $(element).css(state2JSON); 
      self.flag=true; 
      self.options.onChange(); 
     } 
     else{ 
      $(element).css(state1JSON); 
      self.flag=false; 
      self.options.onChange(); 
     }    
    }, duration * 1000); 
} 

//PUBLIC FUNCTIONS 
Plugin.prototype = { 
    init: function(options){   
     var options = $.extend({}, defaults, options);  
     Init(this, options.key, options.from, options.to, options.duration); 
    }, 
    update: function(key, from, to, duration){   
     Init(this, key, from, to, duration);    
    } 
}; 

$.fn[pluginName] = function (options) { 
    var plugin = this.data(dataKey); 

    // has plugin instantiated ? 
    if (plugin instanceof Plugin) { 
     // if have options arguments, call plugin.init() again 
     if (typeof options !== 'undefined') { 
      plugin.init(options); 
     } 
    } else { 
     plugin = new Plugin(this, options); 
     this.data(dataKey, plugin); 
    } 

    return plugin; 
}; 
})(jQuery); 

Voyez comment cela fonctionne maintenant - jsfiddle

+0

Essayez de remplacer '' retour this' pour retourner Plugin' https://jsfiddle.net/haevd4ph/1/ – guest271314

+0

@ guest271314, avez-vous voir le résultat? C'est pareil que le mien. La première div ne fonctionne toujours pas. – Nolesh

+0

Vous n'êtes pas certain du résultat rendu attendu? Comment le premier 'div' devrait-il être rendu? Aussi, pour créer un identifiant unique essayez d'appeler 'uniqueId()' à $ (self.element) .attr ("pluginID", uniqueId()) 'https://jsfiddle.net/haevd4ph/3/ – guest271314

Répondre

0

clearInterval(interval) étant appelée avant interval = setInterval peut avoir été question; essayez également de mettre en flag à this.data()

;(function($) { 
 

 
    var pluginName = "Pulsar", 
 
    dataKey = "plugin_" + pluginName, 
 
    defaults = { 
 
     key: "color", 
 
     from: "#000", 
 
     to: "#fff", 
 
     duration: 5 
 
    }; 
 

 
    var interval = null; 
 

 
    function uniqueId() { 
 
    return 'id-' + Math.random().toString(36).substr(2, 16); 
 
    }; 
 

 
    function Init(key, from, to, duration) { 
 
    $(this).css({ 
 
     WebkitTransition: 'all ease ' + duration + 's', 
 
     MozTransition: 'all ease ' + duration + 's', 
 
     MsTransition: 'all ease ' + duration + 's', 
 
     OTransition: 'all ease ' + duration + 's', 
 
     transition: 'all ease ' + duration + 's' 
 
    }); 
 
    $(this).text(uniqueId()); 
 

 
    var state1, state2; 
 

 
    state1 = '{ "' + key + '" : "' + from + '"}'; 
 
    state2 = '{ "' + key + '" : "' + to + '"}'; 
 

 
    var state1JSON = JSON.parse(state1); 
 
    var state2JSON = JSON.parse(state2); 
 

 
    $(this).css(state1JSON); 
 

 
    interval = setInterval(function() { 
 
     if (!$(this).data().flag) { 
 
     $(this).css(state2JSON); 
 
     $(this).data().flag = true; 
 
     } else { 
 
     $(this).css(state1JSON); 
 
     $(this).data().flag = false; 
 
     } 
 
    }.bind(this), duration * 1000); 
 
    return this 
 
    } 
 

 
    $.fn[pluginName] = function(options) { 
 
    this.data("flag", false); 
 
    var options = $.extend({}, defaults, options); 
 
    return Init.call(this, options.key, options.from, options.to, options.duration); 
 
    }; 
 

 
})(jQuery); 
 

 
$(document).ready(function() { 
 

 
    //FOR SINGLE PROPERTY 
 
    $("#pulsar").Pulsar({ 
 
    duration: 2, 
 
    key: 'textShadow', 
 
    from: '0px 0px 5px rgba(0, 0, 255, 1)', 
 
    to: '0px 0px 30px rgba(0, 0, 255, 1)' 
 
    }); 
 

 
    setTimeout(function() { 
 
    $("#pulsar2").Pulsar({ 
 
     duration: 1, 
 
     key: 'textShadow', 
 
     from: '0px 0px 5px rgba(255, 0, 255, 1)', 
 
     to: '0px 0px 30px rgba(0, 0, 255, 1)' 
 
    }); 
 
    }, 5000); 
 

 
});
body, 
 
html { 
 
    background-color: #000; 
 
} 
 
.pulsar { 
 
    position: absolute; 
 
    font-size: 57px; 
 
    top: 50%; 
 
    left: 50%; 
 
    transform: translate(-50%, -50%); 
 
} 
 
.pulsar2 { 
 
    position: absolute; 
 
    font-size: 47px; 
 
    top: 70%; 
 
    left: 50%; 
 
    transform: translate(-50%, -50%); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> 
 
</script> 
 
<div id="pulsar" class="pulsar">PULSAR</div> 
 
<div id="pulsar2" class="pulsar2">PULSAR 2</div>

jsFiddle https://jsfiddle.net/haevd4ph/5/

+0

@Nolesh Réglage de la version 'interval' à l'élément' .data() 'pour' interval' à effacer en utilisant 'clearInterval ($ (" # pulsar2 "). Data(). Interval)' https://jsfiddle.net/ haevd4ph/6/ – guest271314

+1

Merci, vous m'avez donné une idée! Voir ma question mise à jour. – Nolesh