jQuery 是一个着重简化 DOM 操作,AJAX 调用和事件(en-US)处理的 JavaScript 库。
使用流程:
- 选取元素,返回对象,对其操作。
- 对象中有各种方法操作,针对所有被选取的元素。
- 多个连续的操作可以用“链式”实现。
jQuery的核心思想:
1.提供一个jQuery函数,函数接收一个选择器 jQuery(selector)
2.根据选择器得到一些元素,但不会返回这些元素,而是返回一个对象(jQuery构造出来的对象,称为API)
3.这个对象有各种方法(函数),这些函数可以操作这些元素
[
](https://blog.csdn.net/qq_40282016/article/details/116263519)
jQuery风格/链式风格的DOM库
前置知识:
jQuery对象
window.jQuery() 是全局函数
- jQuery是个函数,可以构造出一个API对象;
- jQuery不是常规意义上的构造函数,却有构造函数的某些特点,因为构造出了一个api对象;
- 而真正意义上的构造函数需要结合new操作符才行
- jQuery对象 全称为jQuery构造出来的对象(口头约定)类比:Object对象表示Object构造出来的对象
链式风格/jQuery风格
- 闭包
- 链式
链式调用
实现基础:$(selector)返回的是一个可以操作被选中元素的api对象
$('div').find('h3').addClass('red').text('hi 我是新加的内容');// 找到所有的div元素,在所有的div元素里找到h3标签,给h3标签增加'red'类,并且替换文本内容
常用API
首先明确:
基于DOM树的结构,一个子节点只能有一个父节点,
故无则“增”,有则“改”,而“改”在既有前提下也是“移”
增
$('<li class="new">new list item</li>'); //创建li$('ul').append('<li>list item</li>'); //将li添加到ul中
删
$div.remove()$div.empty()
改(读&写)
$div.text(?) //读写文本内容$div.html(?) //读写HTML内容$div.css({'color': 'red'}) // 读写style属性,注意此处函数名为 css$div.on('click', fn)$div.off('click', fn)$div.addClass() //向匹配的元素添加指定的类名。$div.attr() //设置或返回匹配元素的属性和值。$div.hasClass() //检查匹配的元素是否拥有指定的类。$div.html() //设置或返回匹配的元素集合中的 HTML 内容。$div.removeAttr() //从所有匹配的元素中移除指定的属性。$div.removeClass() //从所有匹配的元素中删除全部或者指定的类。$div.toggleClass() //从匹配的元素中添加或删除一个类。$div.val() //设置或返回匹配元素的值。
另:在对元素属性进行操作时建议使用JSON形式控制样式
$("#mybtn").css({width:200,height:"200","background-color":"red"})
如何移动元素
.insertAfter()和.after() //在现存元素的外部,从后面插入元素.insertBefore()和.before() //在现存元素的外部,从前面插入元素.appendTo()和.append() //在现存元素的内部,从后面插入元素.prependTo()和.prepend() //在现存元素的内部,从前面插入元素
查
$('#xxx') //返回值并不是元素们,而是一个api对象$('#xxx').find('.red') //查找#xxx里的.red元素$('#xxx').parent() //获取爸爸$('#xxx').children() //获取儿子$('#xxx').siblings() //获取兄弟姐妹$('#xxx').index() //获取排序索引$('#xxx').next() //获取弟弟妹妹$('#xxx').each() //遍历并对每个元素执行fn
DOM对象和jQuery对象
DOM对象:
只能使用DOM 的API,如querySelector 、appendChild
jquery对象:
只能使用jQuery 的API,如 find、each
const div1 = document.querySelector('.test') //直接操作DOMconst div2 = $('.test') //使用jquery
注意:
使用jQuery中声明的变量div2 实际上是jQuery 构造的api对象
写成:const $div = $('div#test')
故:以 $开头的变量,都是jQuery对象,即jQuery构造出来的对象
对象命名风格
DOM对象:普通对象只需原形或者加前缀-el ;如:let eldiv1或div1
jQuery对象:加前缀-$ ;如:let $div2
jQuery原型
- 把共有属性(函数)全部放到jQuery原型上
- $.fn = $.prototype { //各种方法 }
- api.proto指向$.fn
- 原型内的函数变量elements访问不到,则需要用api作为桥梁,在函数内返回值后添加this去访问api
- 原型内补constructor:jQuery,因为重新开辟了一块空间地址会影响之前constructor
手写一个jQuery风格的DOM库
window.$ = window.jQuery = function(selectorOrArrayOrTemplate) {let elements;//先判断要获取的元素们是属于 选择器内 的还是 数组内的if (typeof selectorOrArrayOrTemplate === "string") {if (selectorOrArrayOrTemplate[0] === "<") {// 创建 divelements = [createElement(selectorOrArrayOrTemplate)];} else {// 查找 divelements = document.querySelectorAll(selectorOrArrayOrTemplate);}} else if (selectorOrArrayOrTemplate instanceof Array) {elements = selectorOrArrayOrTemplate;}function createElement(string) { //对象风格的DOM库在 创建元素时 的用法:const container = document.createElement("template");container.innerHTML = string.trim();return container.content.firstChild;}// jQuery方法:api 可以操作elementsconst api = Object.create(jQuery.prototype)// 等价于:const api = {__proto__: jQuery.prototype}Object.assign(api, {elements: elements,oldApi: selectorOrArrayOrTemplate.oldApi})// 等价于:api.elements = elements ;api.oldApi = selectorOrArrayOrTemplate.oldApireturn api};//jquery原型jQuery.fn = jQuery.prototype = {constructor: jQuery, //原型内补充构造者constructor:jQuery,因为重新开辟了一块空间地址会影响之前constructorjquery: true,//增、删、改、查get(index) {return this.elements[index]; //由于原型内的函数变量访问不到前面区块内的elements变量,则需要用api作为桥梁,在函数内返回值后添加this去访问api},appendTo(node) {if (node instanceof Element) {this.each(el => node.appendChild(el));} else if (node.jquery === true) {this.each(el => node.get(0).appendChild(el));}},append(children) {if (children instanceof Element) {this.get(0).appendChild(children);} else if (children instanceof HTMLCollection) {for (let i = 0; i < children.length; i++) {this.get(0).appendChild(children[i]);}} else if (children.jquery === true) {children.each(node => this.get(0).appendChild(node));}},find(selector) {let array = [];for (let i = 0; i < this.elements.length; i++) {const elements2 = Array.from(this.elements[i].querySelectorAll(selector));array = array.concat(this.elements2);}array.oldApi = this; // this 就是 旧 apireturn 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 => {if (array.indexOf(node.parentNode) === -1) {array.push(...node.children);}});return jQuery(array);},print() {console.log(this.elements);},// 闭包:函数访问外部的变量addClass(className) {for (let i = 0; i < this.elements.length; i++) {const element = this.elements[i];element.classList.add(className);}return this;},end() {return this.oldApi; // this 就是新 api}};
