jQuery式的方法鏈核心部分是三點:
1)jquery的包裝器函數(也就是jQuery(),以此來構建包裝器對象),以此構造函數可以產生飽含了原生DOM對象的包裝器對象。
它大概是這個樣子的…(當然跟官方庫的規模跟功能以及實現方式都差很多,我只是寫了個大概的實現方式):
呃…………我的失誤,請大家如果有興趣嘗試下代碼記得不要引入jQuery庫,命名沖突了
代碼如下:
(function(){
//簡化起見不支持子類選擇器屬性選擇器等等,只接受形如".className"或者"#id"或者"tagName"以及它們之間的組合形式 自定義的工具函數(紅色)會在下面說明
function _jQuery(els){
this.elements = new Array();
for (var i = 0; i < els.length; i++) {
var element = els[i];
if (typeof element == 'string') {
element = element.trim(); //防止手抽多打入前後的空格
var sign = element.substr(0, 1);
if (sign == "#") { //按id查找
element = document.getElementById(element.substr(1));
this.elements.push(element);
}
else
if (sign == ".") {
//按類名查找 這裡用到一個自定義的按類名返回dom數組的工具函數getElementsByClassName
element = getElementsByClassName(element.substr(1)); //element此時為數組對象,此方法為自定義見下文
this.elements = this.elements.merge(element);
}
else { //無任何標識符按標簽名查找
element = document.getElementsByTagName(element); //element此時為數組對象
this.elements = this.elements.merge(element);//這個方法可以使得elements數組中只會存在不相同的dom對象 就如同set一樣
}
}
else {
this.elements.push(element);
}
}
}
/*這裡可以開始擴展包裝器對象的原型函數比如
_ jQuery.prototype.addEvent=function(){………}
*/ window['jQuery'] = function(){ return new _jQuery(arguments) }; if (!window['$']) window['$'] = window['jQuery']; })()//自執行匿名函數
OK了 插入下面這段簡單html文檔來測試一下(不要鄙視偶的這個html寫的規范不規范…測試而已)
代碼如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>my function addtion</title>
</head>
<body>
<div id="header">
<p id="header1" class="entrance">
header1
</p>
<p id="header2"class="entrance">
header2
</p>
<p id="header3"class="entrance">
<a href="http://www.poluoluo.com/index.html">header3</a>
</p>
</div>
<hr/>
<div id="content" class="news">
<p id="content1" class="topic">
node1
</p>
<p id="content2" class="topic">
node2
</p>
<p id="content3" class="topic">
<a href="http://www.poluoluo.com/index.html">node3</a>
</p>
</div>
<hr/>
<div id="foot">
<p id="foot1" class="entrance"></p>
</div>
</body>
</html>
輸入:
代碼如下:
var f=$(‘#header').elements[0];
consoles.write("nodeName: "+f.nodeName+"==> Id:"+f.id)
/*自定義的代替alert的一個調試面板工具,由於在用的這個是照搬的某本書上的有點bug而且功能和操作性都不太好,過兩天可能我會修改一下在放上來,自己調試可以用alert代替*/
輸出:
輸入:
代碼如下:
var e=jQuery(' div ',' p').elements; //這裡故意多輸了幾個空格
for(var i=0;i<e.length;i++){
consoles.write("nodeName: "+e[i].nodeName+"==> Id:"+e[i].id);
}
輸出:
雖然整合了dom對象查找的幾個方法,但是還是可以看到每次都使用循環語句來操作dom對象是一件十分煩躁的事情,並且接下來還會以此包裝器為基礎引入很多針對此包裝器對象的方法比如上面的addEvent方法等等,這些方法的引入最終是為了操作對象中包裝的原生dom對象,所以每一個方法中又必須引入for或者while語句,這個引出第二個核心函數==> jQuery.each(){}; 太晚了…明天再總結
本文使用到的工具函數(都是很有用的函數):
代碼如下:
//className:類名 tag:在此標簽名范圍內尋找 parent:在此父節點內尋找
function getElementsByClassName(className, tag, parent){
parent = parent || document; //缺省默認為document
var tag = tag || '*'; //缺省默認為查找所有標簽
var elements = new Array();
var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
var allList = parent.getElementsByTagName(tag);
var element;
for (var i = 0; i < allList.length; i++) {
element = allList[i];
if (element.className.match(re)) {
elements.push(element);
}
}
return elements;
}
代碼如下:
if (!String.prototype.trim) {//去除首尾空格
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
}
}
if (!Array.prototype.merge) {
Array.prototype.merge = function(arr){ //使得數組有類似set的特性 相同的對象無法放入同一個數組不要鄙視偶算法的問題只是闡述下原理
for (var i = 0; i < arr.length; i++) {
var signals=false;
for (var j = 0; j < this.length; j++) {
if (arr[i] == this[j])
signals=true;
}
if (!signals) this.push(arr[i]);
}
return this;
}
}