假设需要实现以下的需求
window.jQuery = ???
window.$ = jQuery
var $div = $('div')
$div.addClass('red') // 可将所有 div 的 class 添加一个 red
$div.setText('hi') // 可将所有 div 的 textContent 变为 hi
封装两个函数
1.给某个节点添加类名
function addClass(node,classes){}
给节点 nodeX添加类名为red:addClass(nodeX, 'red')
2.给某个节点设置文本内容
function setText(node, text) {
node.textContent = text
}
给节点 nodeX设置文本内容为hi:setText(nodeX, 'hi')
命名空间。
“命名空间”是一种设计模式,也就是这个函数名字只属于这个空间。相当于在函数名前面加了个前缀,用于标识该名字的所属空间。它们就不会与已有的相同标识符发生冲突。例:给上述两个函数命名为djdom:
window.djdom = {}
djdom.addClass = addClass
djdom.setText = setText
//调用函数
djdom.addClass(nodex, 'red')
djdom.setText(nodex, 'hi')
改写为 Node.prototype
扩展 Node 接口,直接在Node.prototype上加函数
Node.prototype.addClass = function(classes) {
this.classList.add(classes)
}
Node.prototype.setText = function(text) {
this.textContent = text
}
// 调用函数
nodeX.addClass.call(nodeX, 'red') // 等价于 nodeX.addClass('red')
nodeX.setText.call(nodeX, 'hi') // 等价于 nodeX.getSiblings('hi')
注意:nodeX.function.call(nodeX)为显示执行this
nodeX.function()为隐式执行this
新手最好用call() 调用函数,可以更好的对 this 的理解。this是call的第一个参数。
改写为 Node2
改写为 Node.prototype这种方法,虽然定义函数方便,但确有很大的弊端,不同的人定义的函数会相互覆盖,比较杂乱,因此我们可以重写一个新的接口 Node2,再用它新提供的API 去操控节点。
winddow.node2 = function(node){
return{
addClass:function(node,classes){
node.addClass.add(classes)
}
setText:function(node,text){
node.textContent = text
}
}
}
//调用函数
var node2 = Node2(nodex)
node2.addClass('red')
node2.setText('hi')
改名为 jQuery
winddow.jQuery = function(node){
return{
addClass:function(node,classes){
node.addClass.add(classes)
}
setText:function(node,text){
node.textContent = text
}
}
}
//调用函数
var node2 = jQuery(nodex)
node2.addClass('red')
node2.setText('hi')
jQuery 其实相当于一个构造函数,它接受参数,然后返回一个新的对象,并调用新对象的 API 去操作接受的元素。
jQuery 接受的参数不仅可以是节点,还可以是字符串:
window.jQuery = function(nodeOrSelector){
let node
if(typeof nodeOrSelector === 'string'){ // 判断参数类型
node = document.querySelector(nodeOrSelector) // 根据参数找对应节点
}else{
node = nodeOrSelector // 直接将字符串地址赋值给 node
}
return {
addClass:function(node,classes){
node.addClass.add(classes)
}
setText:function(node,text){
node.textContent = text
}
}
}
// 调用
var node2 = jQuery ('#xxx') // 获取页面中 id 为 xxx 的元素
node2.addClass({'red')
node2.setText('hi')
获取多个API:
// 接受一个 Node 或选择器
window.jQuery = 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]
}
nodes.length = temp.length
} else if (nodeSelector instanceof Node) {
nodes = {
0: nodeOrSelector,
length: 1
}
}
// API
nodes.addClass = function(classes) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(classes)
}
}
// API
nodes.setText = function(text) {
for (let i=0; i<nodes.length; i++) {
nodes[i].textContent = text
}
}
// 返回伪数组 nodes
return nodes
}
// 调用
var nodes = jQuery('li') // 页面中的 li 标签
nodes.addClass('red')
nodes.setText('hi')
模拟jQuery实现API,用alias $
window.jQuery = function(nodeOrSeletor){
let nodes ={}
if(typeof nodeOrSeletor === 'string'){
let temp = document.querySelectorAll(nodeOrSeletor)
for(let i=0;i<temp.length;i++){
nodes[i] = temp[i]
}
nodes.length = temp.length
}else if(nodeOrSeletor instanceof Node){
nodes = {0: nodeOrSeletor,length: 1}
}
nodes.addClass = function(classes){
classes.forEach((value) => {
for(let i=0;i<nodes.length;i++){
nodes[i].classList.add(value)
}
})
}
nodes.setText = function(text){
for(let i=0;i<nodes.length;i++){
nodes[i].textContent = text
}
}
return nodes
}
window.$ = jQuery
var $div = $('div')
$div.addClass(['red']) // 可将所有 div 的 class 添加一个 red
$div.setText('你好') // 可将所有 div 的 textContent 变为 hi
window.$ = jQuery
注意: $表示这是对象是以jQuery构造出来的,表示它是jQuery 的对象,避免与DOM 对象混淆而用错方法。
jQuery的练习题
<ul>
<li></li>
<li></li>
</ul>
请写出$('li')的结构。
答案:$('li')是一个对象,它自身的key有xxx,它的原型(共享属性)为 xxx.prototype,xxx.prototype的 key 有xxx、xxx 和xxx
<div id=x></div>
var div = document.getElementById('x')
var $div = $('#x')
请说出 div 和 $div的联系和区别。
答案:联系:
都是通过id选择器得到相应的node节点
可以相互转换
1、把div变成$div:$div = $('div')
只需要用$()把dom对象包装起来,就能获得一个jQuery对象了
2、把$div 变成div有以下两种方法:
方法1.div= $div[0] //通过[index]来得到相应的dom对象
方法2.div= $div.get(0) //jQuery提供的get(index)方法来得到相应的dom对象
区别:
div是DOM对象,适用于DOM提供的API;
$div是jQuery对象,适用于jQuery提供的API;