原文地址:https://github.com/lianxiaozhuang/blog
轉載請注明出處
1. 點擊add可以添加個自input的內容到div里並實現變顏色
<div id="demo-1"> <input type="" name="" id="" value="好的" /> <button id="add-1">add</button> </div> <div id="demo-2"> <input type="" name="" id="" value="11" /> <button id="add-2">add</button> </div>
整個插件寫在一個立即執行函數里;就是 function(){ }(); 函數自執行;
保證里面的變量不會與外界互相影響,頭部的win啊,doc啊 $ 啊
都是底部的window,document,jQuery的映射;方便內部直接調用;
當然你不引用jq的話頭部的$和底部的jQuery干掉;你若引用了更過的依賴
可以依次添加;最后面的undefined可不寫;最好寫了,保證里面再出現
的undefined是未定義的意思;不被其他東西賦值。
;(function(win,doc,$,undefined){ }(window,document,jQuery))
好了下面是時候展現真正的技術了
function前的 ;(分號) 這不是寫錯了,為了防止那個二貨寫的js結束沒有分號;
而可能發生語法上的混淆報錯;
+function(){ }()
!function(){ }()
~function(){ }()
viod function(){ }()
(function(){ })()
(function(){ }())
function前的 +(加號或者 ! ~);可以把function 直接轉換為可執行的;
和用括號括起來一樣的作用,因為!+-()這些符號的運算符是最高的,所以
會把其后或者其中的當做表達式處理;故函數會自執行,而直接寫function(){}()
會報錯,function(){}只是匿名函數聲明;而寫 var b = function(){}; b()是可以的
;(function(win,doc,undefined){
var addHtml = function(demo,btn){
//插件名,調用的時候直接new一下插件名就行了並傳參數或者傳對象
//(一般這個函數名手寫字母大寫比較好,構造函數嘛,其實也是函數)
//很明顯我要傳id名;這里傳什么都可以的其實;
this.div = doc.getElementById(demo);
//為什么把獲取的id傳給this.div呢?this的指向為調用的實例;
//我們此時姑且認為this就指向這個函數;因為這樣我們之后再想獲取這個
//div就可以直接用this.div了好嗎;而不是在document.getElementById(。。。。)
this.btn = doc.getElementById(btn);
this.Input = this.div.getElementsByTagName("input")[0];
//既然找到了div我們在找下div下面的input;當然你要不input用
//獲取id的形式傳參數我沒有意見
this.num = 0;
//你也可以寫一些其他的默認的東西;比如默認的變量啦;方便下面調用;
//這里寫了什么都不會報錯;只是有用沒用的問題這行可以忽略
this.author = "lianxiaozhuang";
this.init();
//執行下你下面寫的函數吧;你想想;如果整個插件沒有執行函數;
//多不好;一堆方法function就不調用;對;這里是調用的時候最開始
//執行的函數
}
//;給構造函數addHtml對象原型里添加屬性(方法)
addHtml.prototype = {
//給函數寫方法;這里可能不止一個函數;你還記得你在全局里寫一個個
//的function嗎;賊亂找也不好找;把一個個函數都寫到對象的屬性里;
//調用函數就直接調用對象的屬性;
constructor:addHtml,
//構造器指向構造函數;這行其實不寫沒啥毛病;不過防止構造器
//指向Object的情況;你還是裝逼寫上吧; 因為當 addHtml.prototype = {}
//的時候;把一個字面量的對象付給了他的原型上,而{}是由Object產生;
//故此時addHtml的prototype指向了Object,所以要從新指向
init:function(){
//這里的init;你也可以寫成 nimade:function(){ }都沒有問題;
//就是在addHtml函數里this.init();執行下;你明白了這里的this了吧;
//整個插件里this都是只得這個函數(實例);除非你又引入了其他的函數里的
//(其他函數里的可能指向就是window了)
var _self = this;
////把this保存下來防止在局部函數內部取不到(局部函數內部取得this可能
//是別的)
this.btn.onclick = function(){
var _val = _self.Input.value;
var tempdiv = doc.createElement("div");
//創建臨時div存放獲取input的值
tempdiv.innerHTML = _val; //console.log(tempdiv);
_self.div.appendChild(tempdiv);
_self.setColor();
//你把所有方法都寫在init里絕對沒問題;還是那句話;
//說好的松耦合呢;說好的不寫一堆堆的function一層層亂套呢
};
},
setColor:function(){ //console.log(this.div)
this.div.style.color= "red"
},
/*
otherFun(){
//當然你還可以擴展其他方法;這些方法之間都可以互相調用;
// 只要用this.方法名就行了;如果在取不到this比如上面的click函數中的
//this指向點擊的button;只要在寫var _self = this;就可以用_self
// 代替this(函數實例)了;當然_self 也可以寫成別的 比如$this等自定義的
}
*/
}
win.addHtml = addHtml;
//把這個對象附給window底下的 名字叫addHtml的對象;要不你調用的時候
// new addHtml() 怕在window的環境下找不到;
}(window,document))
new addHtml("demo-2","add-2");
//這里是實例2調用插件的代碼
//是不是明白為什么要寫插件了;要封裝;兩個相同組件即使有相同的class名在dom操作的時候
//也不會相互沖突;因為他們都new出來了個自的實例;有自己的this;有自己的一套方法了
//(其實方法都在原型里是公用的;操作各自的dom)
