2016-01-30 5 views
1

Я создал простой плагин JQuery на основе шаблона Boilerplate. Он работает хорошо, кроме одной проблемы. Когда я применяю свой плагин ко второму <div>, первый перестает работать. Более того, все div имеют тот же уникальный идентификатор, который я генерирую при создании нового экземпляра. Как перестроить существующий код, чтобы инкапсулировать переменные и заставить его работать правильно? код ниже мой плагин:Плагин JQuery Boilerplate использует те же внутренние переменные для нового экземпляра

;(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); 

Как это работает вы можете увидеть на jsfiddle

UPDATE: Моя ошибка была объявить переменные в неправильном месте и их использования, поэтому они были использованы все экземпляры, а не конкретный пример. Благодаря guest271314. Он дал мне понять, как исправить мою проблему. Правильный плагин, который работает как шарм находится ниже:

;(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); 

Посмотрите, как он работает сейчас - jsfiddle

+0

Попробуйте заменить 'вернуть this' для' вернуть plugin' https://jsfiddle.net/haevd4ph/1/ – guest271314

+0

@ guest271314, ты увидеть результат? Это то же самое, что и мое. Первый div все еще не работает. – Nolesh

+0

Не знаете, каков ожидаемый результат? Как следует сначала отдать «div»? Кроме того, для создания уникального id попробуйте вызвать 'uniqueId()' в '$ (self.element) .attr (" pluginID ", uniqueId())' https://jsfiddle.net/haevd4ph/3/ – guest271314

ответ

0

clearInterval(interval) вызывается перед тем interval = setInterval может быть проблемой; Также попробуйте установить 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 Версия установки 'interval' в элементе' .data() 'для' interval' должна быть очищена с помощью 'clearInterval ($ (" # pulsar2 "). Data(). Interval)' https://jsfiddle.net/ haevd4ph/6/ – guest271314

+1

Спасибо, ты дал мне идею! См. Мой обновленный вопрос. – Nolesh