自己做一个jQuery的思路
封装两个函数 → 添加命名空间 → 扩展Node原型/无侵入设置
<!--html代码-->
<body>
<h1>text</h1>
<ul>
<li id="item1">选项1</li>
<li id="item2">选项2</li>
<li id="item3">选项3</li>
</ul>
</body>
1、封装两个函数
- 获取所有兄弟元素
//javaScript代码
function getSiblings(node) {
var allChlidren = node.parentNode.chlidren
var array = {
length:0
}
for(let i=0;i<allChildren.length;i++){
if(allChildren[i] !== node){
array[array.length] =allChildren[i]
array.length += 1
}
}
return array
}
//调用方法
getSiblings(item2)
- 给目标元素添加class
//javaScript代码
function addClass(node,classes){
for (let key in classes){
var value = classes[key]
var methodName = value? ' add ' : ' remove '
node.classList[methodName](key)
}
}
// 调用addClass()
addClass(item1,{ a:ture , b:false} )
//语法基础
classList[methodName === classList.methodName
2、添加命名空间
//javaScrip代码
window.textdom = {} // yui
textdom.getSiblings=function (node) {
var allChlidren = node.parentNode.chlidren
var array = {
length:0
}
for(let i=0;i<allChildren.length;i++){
if(allChildren[i] !== node){
array[array.length] =allChildren[i]
array.length += 1
}
}
return array
}
textdom.addClass = function (node,classes){
for (let key in classes){
var value = classes[key]
var methodName = value? ' add ' : ' remove '
node.classList[methodName](key)
}
}
//调用方法
textdom.getSiblings( item3 )
textdom.addClass ( item3,{a:false , b:true } )
了解不扎实的语法基础: for in 语法
3、 扩展Node原型/无侵入设置
上面的函数调用方法都是textdom.addClass()
这样的,假如设想,直接以目标元素为对象进行方法调用,如item2.getClass('red')
,方法有两种。
-
扩展Node原型
Node.prototype.getSiblings =function ( ) {
var allChlidren = this.parentNode.chlidren
var array = { length:0 }
for(let i=0;i<allChildren.length;i++){
if(allChildren[i] !== this){
array[array.length] =allChildren[i]
array.length += 1
}
}
return array
}
Node.prototype.addClass = function(classes){
classes.forEach(
( value ) => this.classList.add( value )
)
}
//调用函数:
item3.getSiblings.call(items)
//等价于item3.getSiblings()
item3.addClass.call( item1,[ 'text' , 'red' , 'blue' ] )
//等价于item3.addClass( ['text' , 'red' , 'blue' ] )
① this知识点 : this是call()的第一个参数
② 箭头函数
③函数调用: f.call ( asThis , input1 , input2 )
其中asThis会被当作this,[ input1 , input2 ]会被当作arguments
-
无侵入设置
第一版 基本实现直接目标元素调用的目的
//javaScript
window.Node2 = function( node ){
return{
getSiblings : function( ){
var allChlidren = this.parentNode.chlidren
var array = { length:0 }
for(let i=0;i<allChildren.length;i++){
if(allChildren[i] !== this){
array[array.length] =allChildren[i]
array.length += 1
}
}
return array
},
addClass : function (classes ) {
classes.forEach(
(value) => this.classList.add(value)
)
}
}
}
var item3 = Node2(item3)
//实现调用
item3.getSiblings()
item3.addClass([ ' red ' ])
console.dir(node2)
//得到的是一个原型为Object.prototype
,里面含有addClass()
等方法的对象
第二版 可以使用选择器确定目标元素
window.Node2 = function( nodeOrSelector ){
let node
if(typeof nodeOrSelector === 'string' ){
node= document.querySelector(nodeOrSelector)
}else{
node= nodeOrSelector
}
return{
getSiblings : function(){
var allChlidren =node.parentNode.chlidren
var array = { length:0 }
for(let i=0;i<allChildren.length;i++){
if(allChildren[i] !==node){
array[array.length] =al lChildren[i]
array.length += 1
}
}
return array
},
addClass : function (classes ) {
classes.forEach(
(value) =>node.classList.add(value)
)
}
}
}
var item3= Node2(item3)
使用了闭包
第三版 可以实现对多个目标元素设置
window.Node2 = function( nodeOrSelector ){
let nodes = { }
if( typeof nodeOrSelector === 'string' ){
let temp = document.querySelectorALL ( nodeOrSelector)
for(let i=0 ; i<temp.length ; i++ ){
nodes[i] = temp[i]
}
node.length = i //得到一个伪数组
}else if (nodeOrSelector instanceof Node){
nodes = {
0:nodeSelector ,
length:1
}//为了保持一致性,的到一个伪数组
}
nodes.addClass = function ( classes ) {
classes.forEach( (value) => {
for( let i=0 ; i< nodes.length ; i++ ){
nodes[i].classList.add(value)
}
})
}
nodes.getText = function ( ){
var texts= [ ]
for ( let i=0 ; i<nodes.length ; i++ ){
texts.push(nodes[i].textContent)
}
nodes.setText = function (text){
for ( let i=0 ; i<nodes.length ; i++ ){
nodes[ i ] .textContext = text
}
}
return nodes
}
了解jQuery的一些特点
jQuery是一个构造函数,这次自制的jQuery没有使用到
prototype
。实际上jQuery构造的实例函数原型是jQuery.prototype
。-
jQuery实例函数的构成:
jQuery的实例是一个数组对象,每个key对应的是一个node节点对象。
jQuery除了DOM操作外,还有动画、AJAX 等模块。
一道常考的面试题
<div id=x></div>
var div = document.getElementById('x');
var $div = $('#x');
请说出 div 和 $div 的联系和区别。
联系:
$div = $( div )
可以将div变成$div
div = $div [0]
或div = $div.get(0)
可以将$div变成div
区别:
div
是一个DOM(element)对象,它的原型是node.prototype
$div
是由jQuery函数构建的数组对象,它的原型是jQuery.prototype
,他的属性和方法有0 1 2.....length selector 等等