Home  >  Article  >  Web Front-end  >  JavaScript plug-in development tutorial (6)_javascript skills

JavaScript plug-in development tutorial (6)_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:16:341058browse

1, opening analysis

What should we talk about in today’s article? Hey hey hey. We will continue the previous article to reconstruct the deficiencies and analyze them step by step in a simple and easy-to-understand way, so that everyone can have a step-by-step improvement process. Without further ado, let’s get to the point. Let us first review the previous

The code for the Js part is as follows:

Copy code The code is as follows:

function ItemSelector(elem,opts){
This.elem = elem ;
This.opts = opts ;
} ;
var ISProto = ItemSelector.prototype ;
ISProto.getElem = function(){
Return this.elem ;
} ;
ISProto.getOpts = function(){
Return this.opts ;
} ;
/* data manip*/
ISProto._setCurrent = function(current){
This.getOpts()["current"] = current ;
} ;
ISProto.getCurrentValue = function(current){
Return this.getOpts()["current"] ;
} ;
/* data manip*/
ISProto.init = function(){
var that = this ;
This.getOpts()["current"] = null ; // Data cursor
This._setItemValue(this.getOpts()["currentText"]) ;
var itemsElem = that.getElem().find(".content .items") ;
This.getElem().find(".title div").on("click",function(){
itemsElem.toggle() ;
}) ;
This.getElem().find(".title span").on("click",function(){
itemsElem.toggle() ;
}) ;
$.each(this.getOpts()["items"],function(i,item){
Item["id"] = (new Date().getTime()).toString() ;
That._render(item) ;
}) ;
} ;
ISProto._setItemValue = function(value){
This.getElem().find(".title div").text(value)
} ;
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
.text(item["text"])
​ .attr("id",item["id"]) ;
If("0" == item["disabled"]){
itemElem.on("click",function(){
            var onChange = that.getOpts()["change"] ;
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
That._setCurrent(item) ;
onChange && onChange(item) ;
})
          .mouseover(function(){
                $(this).addClass("item-hover") ;
})
          .mouseout(function(){
                $(this).removeClass("item-hover") ;
           }) ;
}
       else{
itemElem.css("color","#ccc").on("click",function(){
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
           }) ;
}
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;

The effect is as shown below:

 a)------Non-operable state

b)------Operable status

(2), open up your mind and reconstruct

It is not difficult to see from the code that it has been effectively organized in an object-oriented manner through the grammatical features of "Js", which is much better than the loose procedural form of organization, but there are still many shortcomings. place.

 (1), there are too many repeated codes

(2), unclear division of responsibilities

(3), the process is not perfect

We carry out effective reconstruction based on the above points. We must first sort out the requirements of this component. The functional points are as follows:

 (1), initialize configuration component

Copy code The code is as follows:

$(function(){
var itemSelector = new ItemSelector($("#item-selector"),{
           currentText: "Please Choose Item" ,
items: [
                 {
                   text: "JavaScript" ,
                   value: "js" ,
Disabled : "1"
                                                                                          {
                  text: "Css" ,
                   value: "css" ,
Disabled : "0"
                                                                                          {
                  text: "Html" ,
                   value: "html" ,
Disabled : "0"
            }
] ,
}) ;
itemSelector.init() ;
}) ;


This code is very clear and does not require any modification, but you can extend the function based on the above configuration, such as adding the configuration item "mode" to support multiple options. For example: "checkbox selection mode".

The next step is to complete the initialization logic, as follows:

ISProto.init = function(){
var that = this ;
This.getOpts()["current"] = null ; // Data cursor
This._setItemValue(this.getOpts()["currentText"]) ;
var itemsElem = that.getElem().find(".content .items") ;
This.getElem().find(".title div").on("click",function(){
itemsElem.toggle() ;
}) ;
This.getElem().find(".title span").on("click",function(){
itemsElem.toggle() ;
}) ;
$.each(this.getOpts()["items"],function(i,item){
Item["id"] = (new Date().getTime()).toString() ;
That._render(item) ;
}) ;
} ;

There are many problems with this code, the responsibilities are unclear, and the initialization logic includes the detailed implementation of function points.

Let’s continue looking at the rendering code:

Copy code The code is as follows:

ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
.text(item["text"])
​ .attr("id",item["id"]) ;
If("0" == item["disabled"]){
itemElem.on("click",function(){
            var onChange = that.getOpts()["change"] ;
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
That._setCurrent(item) ;
onChange && onChange(item) ;
})
          .mouseover(function(){
                $(this).addClass("item-hover") ;
})
          .mouseout(function(){
                $(this).removeClass("item-hover") ;
           }) ;
}
       else{
itemElem.css("color","#ccc").on("click",function(){
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
           }) ;
}
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;

The problem is obvious. If repetitive operations are found, they should be reasonably abstracted to achieve the purpose of reuse.

The entire assembly process includes initialization, rendering (event binding), as well as related data operation methods and auxiliary methods for DOM operations.

In summary, after a simple combing, we should establish the operational purpose of the function and the task allocation of the main process line, and everyone should be responsible for it.

So the purpose of our reconstruction is very clear, right! It means abstraction of function points and friendly division of responsibilities. So how do we achieve that?

The first step is to establish the process function method: (method interface)

Copy code The code is as follows:

ISProto.init = function(){
// put you code here !
} ;
ISProto._render = function(){
// put you code here !
} ;

The second part, establishing the abstract method interface:

Copy code The code is as follows:

ISProto._fnItemSelectorDelegateHandler = function(){
// put you code here !
} ;
ISProto._fnTriggerHandler = function(){
// put you code here !
} ;
ISProto._addOrRemoveClass = function(){
// put you code here !
} ;

The third step is to establish a data operation interface:

Copy code The code is as follows:

ISProto._setCurrent = function(){
// put you code here !
} ;
ISProto._getCurrent = function(){
// put you code here !
} ;

There are also some complete source codes below, here are just ideas.

(3), complete code for learning, this code has been tested

Copy code The code is as follows:

function ItemSelector(elem,opts){
This.elem = elem ;
This.opts = opts ;
This.current = -1; // Data cursor
} ;
var ISProto = ItemSelector.prototype ;
/* getter api*/
ISProto.getElem = function(){
Return this.elem ;
} ;
ISProto.getOpts = function(){
Return this.opts ;
} ;
ISProto._getCurrent = function(){
Return this.current ;
} ;
/* getter api*/
/* data manip*/
ISProto._setCurrent = function(current){
This.current = current ;
} ;
ISProto._setItemText = function(text){
This.getElem().find(".title div").text(text) ;
} ;
/* data manip*/

/* update on 2015 1/31 23:38 */
ISProto._fnTriggerHandler = function(index,text,value){
If(this._isDisabled(value)){
index = -1 ;
         text = this.getOpts()["currentText"] ;
}
This._setItemText(text) ;
This._setCurrent(index) ;
This.getElem().find(".content .items").hide() ;
} ;
ISProto._addOrRemoveClass = function(elem,className,addIs){
If(addIs){
           elem.addClass(className) ;
}
else{
          elem.removeClass(className) ;
}
} ;
ISProto._fnItemSelectorDelegateHandler = function(){
var that = this ;
This.getElem().on("click","[data-toggle]",function(){
That.getElem().find(".content .items").toggle() ;
}) ;
} ;
ISProto._isDisabled = function(value){
Return ("1" == value) ? true : false ;
} ;
/* update on 2015 1/31 23:38 */
ISProto.init = function(){
var that = this ;
This._fnItemSelectorDelegateHandler() ;
$.each(this.getOpts()["items"],function(i,item){
Item["index"] = i ;
That._render(item) ;
}) ;
This._fnTriggerHandler(this._getCurrent(),this.getOpts()["currentText"],"1") ;
} ;
ISProto._render = function(item){
var that = this ;
var itemElem = $("
").text(item["text"]).attr("id",item["index"]) ;
var activeClass = ("0" == item["disabled"]) ? "item-hover" : "item-disabled-hover" ;
itemElem.on("click",function(){
That._fnTriggerHandler(item["index"],item["text"],item["disabled"]) ;
})
.mouseover(function(){
That._addOrRemoveClass($(this),activeClass,true) ;
})
.mouseout(function(){
That._addOrRemoveClass($(this),activeClass,false) ;
}) ;
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;
 

(4), final summary

(1) Reasonably analyze functional requirements using object-oriented thinking.

(2) Organize our plug-in logic in the form of classes.

(3) Continuously reconstruct the above example. How to perform reasonable reconstruction? Don’t over-design and be comfortable with it. The recommended way is to combine procedural design with object-oriented design.

(4), related functions will be expanded in the next article, such as the "mode" attribute, which supports checkbox multi-selection mode when it is "1", but now it is only the default drop-down mode.

Look at my article, is it much better than the previous code? Friends should also think more and do more when doing their own projects, and try to make their code more reasonable.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn