jQuery学习
jQuery的设计模式
- 不用 new 的构造函数
- 重载:$(支持多种参数)
- 用闭包隐藏细节
- getter / setter:$div.text() 即可读也可写
- .prototype 的别名
- 适配器:jQuery 针对不同浏览器使用不同代码
jQuery 如何获取元素
jQuery 通过基础的 DOM api document.querySelectorAll 获取元素
$('#xxx') //返回值并不是元素,而是一个 api 对象
$('#xxx').find('.red') //查找 #xxx 里的 .red 元素
$('#xxx').parent() //获取爸爸
$('#xxx').children() //获取儿子
$('#xxx').siblings() //获取兄弟
$('#xxx').index() //获取排行老几(从0开始)
$('#xxx').next() //获取弟弟
$('#xxx').prev() //获取哥哥
$('.red').each(fn) //遍历并对每个元素执行 fn
部分代码实现
find(selector) {
let array = [];
for (let i = 0; i < this.elements.length; i++) {
array = array.concat(
Array.from(this.elements[i].querySelectorAll(selector))
);
}
array.oldApi = this;
return jQuery(array);
},
each(fn) {
for (let i = 0; i < this.elements.length; i++) {
fn.call(null, this.elements[i], i);
}
return this;
},
parent() {
const array = [];
this.each((node) => {
if (array.indexOf(node.parentNode) === -1) {
array.push(node.parentNode);
}
});
return jQuery(array);
},
children() {
const array = [];
this.each((node) => {
array.push(...node.children);
});
return jQuery(array);
},
get(index) {
return this.elements[index];
},
jQuery 的链式操作
$('#xxx').children().find('red').each(fn)
通过不断的返回一个api对象,使得代码能立即调用下一个api,这就是链式操作
jQuery 如何创建元素
$('<div><span>1</span></div>') //创建 div
通过判断输入的参数的第一个字符是否为<来判断是不是HTML语法,如果是,则调用了一个createElement函数,该函数通过 DOM api 创建元素
代码实现:
window.$ = window.jQuery = function (selectorOrArrayOrTemplate) {
let elements;
if (typeof selectorOrArrayOrTemplate === "string") {
if (selectorOrArrayOrTemplate[0] === "<") {
elements = [createElement(selectorOrArrayOrTemplate)];
} else {
elements = document.querySelectorAll(selectorOrArrayOrTemplate);
}
} else if (selectorOrArrayOrTemplate instanceof Array) {
elements = selectorOrArrayOrTemplate;
}
function createElement(string) {
const container = document.createElement("template");
container.innerHTML = string.trim();
return container.content.firstChild;
}
}
jQuery 如何移动元素
$('#div').appendTo(document.body) //插入到 body 中
代码实现:
appendTo(node) {
if (node instanceof Element) {
this.each((el) => node.appendChild(el)); //$.each为遍历
} else if (node.jquery === true) {
this.each((el) => node.get(0).appendChild(el)); //$.get(index)为找到第0个元素
}
},
jQuery 如何修改元素的属性
$div.text('xxx') //读写文本内容
$div.html('xxx') //读写 HTML 内容
$div.attr('title', 'xxx') //读写属性
$div.css({color: 'red'}) //读写 style
$div.addClass('blue')
$div.on('click', fn)
$div.off('click', fn)
部分代码实现:
addClass(className) {
for (let i = 0; i < this.elements.length; i++) {
this.elements[i].classList.add(className);
}
return this;
}