1. Opening analysis
In the previous two articles, we mainly talked about how to develop plug-ins in jQuery, and how to combine process design with object-oriented thinking design.
How to design a plug-in? The two methods have their own advantages and disadvantages to learn from each other's strengths and weaknesses. This series of articles is learning-oriented, and everyone decides how to use the specific scenarios. So starting from this article today, we will use examples to develop our own plug-in library from shallow to deep. Hehehe, say less nonsense, get to the point. Directly on the actual renderings:
You can see it. This is a tab plugin. We may come across it when we make single-page applications ("SPA") every day. Let's take today's example.
We build a system based on BS structure, which will consist of several modules, which are all the components of the construction system. Through this plug-in, we can effectively manage our modules
Let’s analyze the experience form and user interactivity in detail below.
(II), case analysis
(1) First, determine what this plugin does. Let’s take a look at the call method of the plug-in and the configuration parameter description. The following code:
The code copy is as follows:
bigbear.ui.createTab($("#tab"),{
buttonText: "Add module",
result: [
{
text : "Wizard prompt",
url : "help.html",
showClose : "0",
status : "1"
} ,
{
text : "Student Information",
url : "info.html",
showClose : "1",
status : "1"
} ,
{
text : "Student Classification",
url : "category.html",
showClose : "1",
status : "1"
} ,
{
text : "Big Bear {{bb}}",
url : "bb.html",
showClose : "1",
status : "1"
} ,
{
text : "Beta test module",
url : "test.html",
showClose : "1",
status : "1"
}
]
}) ;
"bigbear.ui.createTab" contains two parameters. The first is the dom node object and the second is the plug-in parameter option. "buttonText" represents the text description of the operation button in the "Tab" plug-in.
"result" is an array that contains the properties of the tab item, including the text description, the URL used to request it when clicking the tab item, "showClose" represents whether the tab option displays the close button.
"status" represents the status of the option, which is the on state by default, and there may be a closed state, which is expressed as: 1-Open and 0-Open respectively.
(2) What are the functions involved?
Through optional parameters, relevant option entries are dynamically generated, as follows:
The code copy is as follows:
bigbear.ui.createTab($("#tab"),{
buttonText: "Add module",
result: [
{
text : "jQuery source code analysis",
url : "help.html",
showClose : "0",
status : "1"
} ,
{
text : "Big Bear {{bb}}}",
url : "bb.html",
showClose : "1",
status : "1"
}
]
}) ;
The effect is as follows:
You can freely add and delete entries options, as shown in the following effect:
The above picture shows one of these situations. When there is no module, a message will be prompted.
This is the second case, and those that were previously deleted can be restored.
(III), complete code for learning , this code has been tested, including directory structure and related files.
(1), html
The code copy is as follows:
<body>
<div>
Big Bear {{bb}} - DXJ UI ------ Tab
</div>
<div>
<div id="tab">
<div>
<div>
+ Add student information
</div>
<div>
<!--<div><span>X</span>Welcome Page</div>
<div><span>X</span>User Management</div>
<div><span>X</span>Bigbear</div>-->
</div>
</div>
<div>
</div>
<div>
<!--<div>
<div><span>Name:</span><input type="text" /></div>
<div><span>Note: </span><textarea></textarea></div>
</div> <div><input type="button" value="Save" /></div>
-->
</div>
</div>
</div>
</body>
(2), css file code
The code copy is as follows:
.dxj-ui-hd {
padding:0px ;
margin : 0 auto;
margin-top:30px;
width:780px;
height:60px;
line-height: 60px;
background: #3385ff;
color:#ffff;
font-family: "Microsoft Yahei";
font-size: 28px;
text-align: center;
font-weight:bold;
}
.dxj-ui-bd {
padding:0px ;
margin : 0 auto;
width:778px;
padding-top : 30px ;
padding-bottom : 30px ;
overflow: hidden;
border:1px solid #3385ff;
}
.dxj-ui-bd #tab {
padding:0px ;
margin : 0 auto;
width:720px;
overflow: hidden;
}
.dxj-ui-bd #tab .title {
width:720px;
overflow: hidden;
border-bottom:2px solid #3385ff;
}
.dxj-ui-bd #tab .title .adder {
width:160px;
height:32px;
line-height: 32px;
background: #DC143C;
color:#ffff;
font-family: "Microsoft Yahei";
font-size: 14px;
text-align: center;
font-weight:bold;
float : left;
cursor:pointer;
}
.dxj-ui-bd #tab .title .items {
height:32px;
margin-left:20px;
width:540px;
overflow: hidden;
float : left;
}
.dxj-ui-bd #tab .title .items div {
padding:0px;
margin-left:10px;
width:96px;
height:32px;
line-height: 32px;
background: #3385ff;
color:#ffff;
font-family: arial ;
font-size: 12px;
text-align: center;
position:relative;
float : left;
cursor:pointer;
}
.dxj-ui-bd #tab .title .items div span.del {
width:16px;
height:16px;
line-height: 16px;
display:block;
background: #DC143C;
position:absolute;
right:0 ;
top:0;
cursor:pointer;
}
.dxj-ui-bd #tab .content {
width:716px;
padding-top:30px;
overflow: hidden;
border:2px solid #3385ff;
border-top:0px;
min-height:130px;
text-align:center;
}
.dxj-ui-bd #tab .content table {
margin : 0 auto ;
}
.dxj-ui-bd #tab .content div.c {
padding-top : 20px ;
padding-left:20px;
background:#eee;
height:140px;
}
.dxj-ui-bd #tab .content div.c .input-content {
margin-top : 10px ;
font-family: arial ;
font-size: 12px;
}
.dxj-ui-bd #tab .console-panel {
width:716px;
padding-top:20px;
padding-bottom:20px;
overflow: hidden;
border:2px solid #3385ff;
border-top:0px;
border-bottom:2px solid #3385ff;
background:#fff;
display:none;
}
.active {
font-weight:bold ;
}
(3), the Js code is as follows:
The code copy is as follows:
$(function(){
bigbear.ui.createTab($("#tab"),{
buttonText: "Add module",
result: [
{
text : "Wizard prompt",
url : "help.html",
showClose : "0",
status : "1"
} ,
{
text : "Student Information",
url : "info.html",
showClose : "1",
status : "1"
} ,
{
text : "Student Classification",
url : "category.html",
showClose : "1",
status : "1"
} ,
{
text : "Big Bear {{bb}}",
url : "bb.html",
showClose : "1",
status : "1"
} ,
{
text : "Beta test module",
url : "test.html",
showClose : "1",
status : "1"
}
]
}) ;
}) ;
(function($){
var win = window;
var bb = win.bigbear = win.bigbear || {
ui : {}
} ;
var ui = bb.ui = {} ;
var Tab = function(elem,opts){
this.elem = elem ;
this.opts = opts ;
} ;
var tabProto = Tab.prototype;
tabProto._deleteItem = function(item){
var that = this ;
this.getElem().find(".title .items div")
.eq(item["index"])
.fadeOut(function(){
that._resetContent() ;
that._updateStatus(item);
that._triggerItem(item["index"] + 1);
that.getElem().find(".title .adder").trigger("click");
}) ;
} ;
tabProto._triggerItem = function(next){
var nextStatus = this._getStatus(next) ;
var items = this.getElem().find(".title .items div");
next = items.eq(next) ;
if(next.size() && "1" == nextStatus){ //The subsequent dom node exists
next.trigger("click");
}
else{
items.eq(0).trigger("click");
}
} ;
tabProto._getStatus = function(index){
var status = "" ;
$.each(this.getOpts()["result"],function(i,item){
if(index == item["index"]){
status += item["status"] ;
return false ;
}
}) ;
return status ;
} ;
tabProto._updateStatus = function(item){
var status = item["status"] ;
item["status"] = ("1" == status) ? "0" : "1" ;
} ;
tabProto.init = function(){
var that = this ;
this.getElem().find(".title .adder")
.text("+" + this.getOpts()["buttonText"])
.on("click",function(){
that._toggleConsolePanel(function(){
var root = that.getElem().find(".console-panel").empty();
$.each(that.getOpts()["result"],function(i,item){
if("0" == item["status"]){
var elem = $("<div style='float:left';></div>")
.data("item",item)
.appendTo(root);
$("<input type='radio' name='addmod' />").appendTo(elem) ;
$("<span></span>").text(item["text"]).appendTo(elem);
}
}) ;
if(root.find("div").size()){
$("<input type='button' value='add module' style='margin-left:20px'/>")
.on("click",function(){
var data = root.find("input[type=radio]:checked").parent().data("item");
that._updateStatus(data);
that.getElem().find(".title .items div").eq(data["index"]).fadeIn().trigger("click");
that.getElem().find(".title .adder").trigger("click");
})
.appendTo(root);
}
else{
root.text("No items to add yet!");
}
}) ;
}) ;
$.each(this.getOpts()["result"],function(i,item){
item["index"] = i ;
that._render(item);
}) ;
this.getElem().find(".title .items div")
.eq(0)
.trigger("click"); // Assume that there must be one, otherwise the plug-in will not make much sense!
} ;
tabProto._toggleConsolePanel = function(callback){
this.getElem().find(".console-panel").slideToggle(function(){
$.isFunction(callback) && callback() ;
}) ;
} ;
tabProto._resetContent = function(){
this.getElem().find(".content").html("");
} ;
tabProto._setContent = function(html){
this.getElem().find(".content").html(html);
} ;
tabProto._getContent = function(url){
return $.ajax({
url : url
}) ;
} ;
tabProto._render = function(data){
var that = this ;
var item = $("<div></div>")
.text(data["text"])
.on("click",function(){
that._setCurrent(data["index"]) ;
that._getContent(data["url"]).done(function(result){
that._setContent(result);
})
.fail(function(){
throw new Error("Net Error !");
});
})
.appendTo(this.getElem().find(".title .items")));
if("1" == data["showClose"]){
$("<span class='del'>X</span>")
.on("click",function(){
if(win.confirm("Does this item be deleted?")){
that._deleteItem(data);
return false ; // stop bubbles
}
})
.appendTo(item);
}
} ;
tabProto._setCurrent = function(index){
var items = this.getElem().find(".title .items div").removeClass("active");
items.eq(index).addClass("active");
var contents = this.getElem().find(".content .c").hide();
contents.eq(index).show();
} ;
tabProto.getElem = function(){
return this.elem ;
} ;
tabProto.getOpts = function(){
return this.opts ;
} ;
ui.createTab = function(elem,opts){
var tab = new Tab(elem,opts) ;
tab.init();
return tab ;
} ;
})(jQuery);
(IV), final summary
(1) A reasonable analysis of functional requirements in an object-oriented way of thinking.
(2), organize our plug-in logic in a class way.
(3) Continuously reconstruct the above examples, how to reasonably reconstruct that? Don’t over-design, be at ease. The recommended method is to combine process design with object-oriented thinking design.
(4) Think about whether the options in the tab can be independently classified into separate classes in the example above? For example, "Item", then how to modify the "Tab" class? Think with questions. . .
The above is the entire content of this article. We will continue to improve this plug-in in the future. If you like this article, please give me a thumbs up.