背景css
節點類型html
var NODE_TYPE_ELEMENT = 1; // element var NODE_TYPE_ATTRIBUTE = 2; // attribute var NODE_TYPE_TEXT = 3; // text var NODE_TYPE_COMMENT = 8; // comment var NODE_TYPE_DOCUMENT = 9; // document var NODE_TYPE_DOCUMENT_FRAGMENT = 11; // document fragment
對於 jqLite主要實現如下方法node
實現原理:主要是判斷 setAttribute是否存在,藉助 setAttribute 和getAttribute 方法實現jquery
具體實現:主要是藉助 getAttribute 查找該元素原始的css 內容,而後查找這個css 內容中是否擁有新的class,若是沒有就添加進去,而後把更新以後的css 內容 使用setAttribute 更新css 內容。緩存
function jqLiteAddClass(element,cssClasses){ if(element && element.setAttribute){ // 獲取原來的css var exisingClass = ('' + (element.getAttribute('class') || '') + '').replace(/[\n\t]/g.' '); forEach(classClasses.split(' '),function(cssClass){ cssClass = trim(cssClass); // 若是存在的class 中不存在你須要添加的對象 if(existingClasses.indexOf('' + cssClass + '') === -1){ // 添加進去 existingClasses += cssClass + ' '; } }) // 更新元素的css 結果 element.setAttribute('class',trim(exisingClass )); } }
實現原理:主要是藉助 parentNode 和 insertBefore 實現app
具體實現:主要是查找到 element.nextSibling 將 newElement 插入到 nextSibling以前。dom
after:function(element,newElement){ var index = element,parent = element.parentNode; newElement = new JQLite(newElement); for(var i = 0,ii = newElement.length;i<ii;i++){ var node = newElement[i]; // 主要藉助於 insertBefore 方法 parent.insertBefore(node,index.NextSibling); index = node; } }
實現原理:主要是先利用nodeType 節點的類型,只有符合條件的節點類型才能被append ,而後利用appendChild方法實現append 功能
函數
具體實現:獲取節點類型(nodeType),若是不知足條件的節點類型則不作處理,不然就將新要插入的節點插入到節點中去(appendChild)oop
append:function(element,node){ var nodeType = element.nodeType; if(nodeType !== 1 && nodeType !== 11){ return; } node = new JQLite(node); for(var i = 0,ii = node.length;i<ii;i++){ var child = node[i]; // 主要經過appendChild 方法實現 element.appendChild(child); } }
實現原理:setAttribute,getAttribute,removeAttributeui
主要實現:先獲取節點類型,若是節點類型不知足條件,則直接返回,若是知足則再判斷名稱是不是boolean 類型(multiple,selected,checked,disabled,readyOnly,required,open),則賦值true 或者 false。再者去判斷是否存在value 若是存在就調用setAttribute 方法設置屬性,若是不存在,則調用getAttribute 方法獲取屬性。
var BOOLEAN_ATTR = {}; forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','),function(value){ BOOLEAN_ATTR[lowercase(value)] = value; }) attr:function(element,key,value){ var nodeType = element.nodeType; if(nodeType === 3 || element === 2 || element === 8){ return; } var lowercasedName = lowercase(name); // 是否知足boolean 類型 的參數 if(BOOLEAN_ATTR[lowercasedName]){ if(isDefined(value)){ if(!!value){ element[name] = true; element.setAttribute(name,lowercasedName); } else{ element[name] = false; element.removeAttribute(name); } } else{ // element.attribute.getNamedItem(name) 是 xml dom 的方法 return (element[name] || (element.attribute.getNamedItem(name) || noop).specified) ? lowercasedName: undefined; } } // value 是否存在 else if(isDedined(value)){ element.setAttribute(name,value); } // 查看是否存在getAttribute 方法 else if(element.getAttribute){ // the extra argument '2' is to get the right thing for a.href in ie,see jquery code // some element (eg:Document) don't have get attribute, so return undefined; var ret = element.getAttribute(name,2); return ret === null ? undefined : ret; } }
比較複雜 待定
實現原理: childNodes
主要實現:主要遍歷element 對象的 childNodes,而後判斷 子節點類型是不是 NODE_TYPE_ELEMENT類型,若是是就返回
children:function(element){ var children = []; forEach(element.childNodes,function(ele){ // 符合條件的 節點類型 if(ele.nodeType === 2){ children.push(ele); } }) return children; }
實現原理:cloneNode
主要實現:主要利用cloneNode 方法實現的
function jqLiteClone(element){ return element.cloneNode(true); }
實現原理:contentDocument childNodes
主要實現:首先獲取元素的contentDocument 對象,若是獲取不到就獲取他的childNodes 再獲取不到 返回 [ ]
content:function(element){ return element.contentDocument || element.childNodes || []; }
css
實現原理: element.style
主要實現:主要根據 element.style 而後繼續獲取所須要的name ,也能夠給name 賦值。
css:function(element,name,value){ name = camelCase(name); // 若是定義了value 的值 if(isDefined(value)){ element.style[name] = value; } else{ return element.style[name]; } }
data
detach
empty
實現原理: this[index]
主要實現: 若是 index 是正數的話,則取其中的第N個元素,不然取 this.length + index 個元素
eq:function(index){ return index >=0 ? jqLite(this[index]) : jqLite(this[this.length + index]); }
實現原理:getElementByTagName
主要實現:主要根據getElementByTagName實現
find:function(element,selector){ if(element.getElementByTagName){ return element.getElementByTagName(selector); } else { return []; } }
hasClass
實現原理:getAttribute
主要實現:先判斷要選擇的元素是否擁有getAttribute方法,而後利用 getAttribute 搜索出class 實現
function jqLiteHasClass(element,selector){ if(!element.getAttribute){ return false; } var exitClasses = ' ' + (element.getAttribute('class') || ' ') + ' '; exitClasses = exitClasses.replace(/\n\t/g,' '); return exitClasses.indexOf(' ' + selector + ' ') > -1; }
實現原理:innerHTML
主要實現:若是是獲取某個元素的html 利用的是 innerHTML屬性,若是是給某個屬性賦值的話,
html:function(element,value){ // 若是 value 爲空的話,則表示須要獲取element 對象的 html 值,也就是innerHTML的內容 if(isUndefined(value)){ return element.innerHTML; } // 若是value 存在的話,則表示賦值操做 }
實現原理: getAttribute('class') , indexOf()
主要實現: 主要經過 getAttribute('class') 獲取到全部的 class 內容,而後經過indexOf 查看class 是否存在裏面
function hasClass(element,selector){ if(!element.getAttribute) return false; return (element.getAtribute('class')).replace(/[\n\t]/g, '' ).indexOf( selector ) > -1; }
實現原理:nextElementSibling
主要實現:直接返回對象的 nextElementSibling
next:function(element){ return element.nextElementSibling; }
on
off
one
實現原理:parentNode, nodeType
主要實現:獲取element 的 parentNode 對象 ,而後判斷parent 對象類型是否合法,合法就返回,不合法就返回null
parent:function(element){ var parent = element.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }
實現原理: nodeType fristChild insertBefore
主要實現:先判斷類型,若是符合類型,則先獲取元素的firstChild,而後遍歷須要插入的節點,調用insertBefore插入進去就能夠了
prepend:function(element,node){ if(element.nodeType === 1){ var index = element.firstChild; forEach(new JQLite(node),function(child){ element.insertBefore(child,index); }); } }
實現原理:非常霸氣的直接取對象的屬性
主要實現:
prop:function(element,name,value){ if(isDefined(value)){ element[name] = value; } else { return element[name]; } }
實現原理: DOMContentLoaded, load ,document.readyState
主要實現:
ready:function(fn){ var fired = false; function trigger(){ if(fired) return; tired = true; fn(); } if(document.readyState === 'complete'){ setTimeout(trigger,1); } else{ this.on('DOMContentLoaded',trigger); JQLite(window).on('load',trigger); } }
實現原理:parentNode,removeChild
主要實現:
function jqLiteRemove(element,keepData){ if(!keepData){ // 待定。。。 } var parent = element.parentNode; if(parent){ parent.removeChild(element); } }
實現原理: removeAttribute
具體實現:
removeAttr:function(element,name){ element.removeAttribute(name); }
實現原理: setAttribute ,getAttribute('class'), replace(cssClass',' ')
具體實現: 主要利用getAttribute 獲取class 內容,而後利用replace替換掉須要移除的屬性 .
function jqLiteRemoveClass(element,cssClasses){ if(cssClasses && element.setAttribute){ forEach(classClasses.split(' '),function(cssClass){ element.setAttribute('class',trim( ('' + (element.getAttribute('class')) + '') // 移除無效符號 .replace(/[\n\t]/g, ' ') // 移除 須要移除的屬性 .replace('' + trim(cssClass) + '', ''); )) }) } }
removeData
實現原理:
具體實現:仍是須要經過查找到須要替換元素的parentNode 節點,而後利用 replaceChild實現
replaceWith:function(element,replaceNode){ var index,parent = element.parentNode; // 移除element 綁定的數據 forEach(new JQLite(replaceNode),function(node){ if(index){ parent.insertBefore(node,index.nextSibling); } else{ parent.replaceChild(node,element); } index = node; }) }
實現原理:textContent
具體實現:
text: (function(){ getText.$dv = ''; return getText; function getText(element,value){ if(isUndefined(value)){ var nodeType = element.nodeType; // 必須知足條件才行。 return (nodeType === 1|| nodeType === 3) ? element.textContent :''; } element.textContent = value; } })()
toggleClass
實現原理:
主要實現:首先判斷是否存在第三個參數,若是存在的話,則根據參數是否爲true 則調用addClass 不然調用 removeClass,若是不存在的話,則調用hasClass函數,是否存在這個class ,根據是否存在設置第三個參數。
toggleClass:function(element,selector,condition){ if(selector){ forEach(selector.split(' '),function(className){ var classCondition = condition; if(isUndefined(classCondition)){ classCondition = !hasClass(element,className); } (classCondition) ? addClass(element,className) : removeClass(element,className); }) } }
triggerHandler
unBind
實現原理: value , text , nodeName
主要實現: 主要區分select 對象, 由於能夠multiple 多選,因此須要判斷nodeName 是不是 select
val:function(element,value){ if(isUndefined(value)){ if(element.multiple && nodeName_(element) === 'select'){ var result = []; forEach(element.options,function(option){ if(option.selected){ result.push(option.value || option.text); } }); return result.length === 0 ? null: result; } return element.value; } // 不然就是賦值操做 element.value = value; }
實現原理:
主要實現: 找到element 元的父親,將自身緩存下,而後將wrapNode替換掉本來直接所在的element 對方,而後將element 插入到wrapNode中去。
wrap:function(element,wrapNode){ // 克隆一個對象 wrapNode = jqLite(wrapNode).eq(0).clone()[0]; // 獲取父親 var parent = element.parentNode; if(parent){ // 若是存在父親,就將element替換成wrapNode 對象 parent.replaceChild(wrapNode,element); } // wrapNode節點插入 child 節點。 wrapNode.appendChild(element); }