简化版自己实现jQuery
1. == 与===
尽量不要用 == 规则太复杂
用===只需要注意两点,1.NaN===NaN,false,2.所有对象===也都是false,因为地址不一样.
2.自己写jQuery与用jQuery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery-Study</title>
<script src="01_myjQuery1.js"></script>
<script src="jQuery3.3.1min.js"></script>
<style>
.red{
color: red;
}
.blue{
color: blue;
}
.big{
font-size: larger;
}
.green{
color: green;
}
.pink{
color: pink;
}
</style>
</head>
<body>
<!--ul>li[id=item$]{这是li$}*8-->
<ul>
<li id="item1">这是li1</li>
<li id="item2">这是li2</li>
<li id="item3">这是li3</li>
<li id="item4" class="xxx">这是li4</li>
<li id="item5">这是li5</li>
<li id="item6">这是li6</li>
<li id="item7">这是li7</li>
<li id="item8">这是li8</li>
</ul>
<button id="x">x</button>
<ol id="ol2">
<li id="i1">1</li>
<li id="i2">2</li>
<li id="i3">3</li>
<li id="i4">4</li>
<li id="i5">5</li>
</ol>
</body>
<script>
console.log('直接使用');
console.log(getSiblings(item1));
console.log('直接使用');
addClass(item2,{a:true,xxx:false,c:true});
console.log(item2);
</script>
<script src="UseJquery.js"></script>
</html>
01_myjQuery1.js
// 得到兄妹结点
//传入的参数是一个节点,返回兄妹结点的数组
function getSiblings(node) {
var allSilings = node.parentNode.children;
var siblingsArray = {length:0};
for (let i = 0; i < allSilings.length; i++) {
if (allSilings[i]!==node){
siblingsArray[siblingsArray.length] = allSilings[i];
siblingsArray.length++;
}
}
return siblingsArray;
}
//添加或删除class
//传入的第一个参数是结点,第二个参数是对象, 这个对象里是key:value,key就是要操作的class,value判断操作类型,true添加,false删除
function addClass(node,object){
for (let key in object){
//对象调用方法的两种方式:
// obj.f()
// obj['f']()
var methodName;
methodName = object[key] ? 'add':'remove';
node.classList[methodName](key);
/*上面两句代码相当于
if (object[key]) {
node.classList.add(key);
}else {
node.classList.remove(key);
}*/
}
}
window.mydom = {};
mydom.getSiblings = getSiblings;
mydom.addClass = addClass;//命名空间,常用的设计或者组合就叫做设计模式.哈希,数组,都是一种设计模式
//所以jQuery就是这样来的,jQuery就是一个命名空间,里面有很多函数.
// 命名空间作用:1.方便识别库,2.如果都放在window里,可能会覆盖别的库,所以命名空间是为了防止覆盖别的函数
window.onload = function () {
// 测试
// 如何直接使用item3.addclass()?,item3.getSiblings()?
// 方法一:给原型链加公有属性公有方法,但是有缺点,容易覆盖
Node.prototype.getSiblings = function () {
var allSilings = this.parentNode.children;//谁调用这个函数,this就是谁
var siblingsArray = {length:0};
for (let i = 0; i < allSilings.length; i++) {
if (allSilings[i]!==this){
siblingsArray[siblingsArray.length] = allSilings[i];
siblingsArray.length++;
}
}
return siblingsArray;
}
let item3 = document.getElementById('item3');
// console.log(item3.getSiblings.call(item3));如果用cal.第一个参数就是函数里的this,如果不用call(),那么this就自动变成了item3
console.log(' 方法一:');
console.log(item3.getSiblings());//测试成功
Node.prototype.addClass = function (object) {
for (let key in object){
var methodName;
methodName = object[key] ? 'add':'remove';
this.classList[methodName](key);
}
}
// item3.addClass.call(item3,{a:true,xxx:false,c:true});;如果用call.第一个参数就是函数里的this,如果不用call(),那么this就自动变成了item3
console.log(' 方法一:');
item3.addClass.call(item3,{a:true,xxx:false,c:true});
// item3.addClass({a:true,xxx:false,c:true});
console.log(item3);//测试成功
// 如何直接使用item3.addclass()?,item3.getSiblings()?
// 方法二:因为方法一在原型中添加函数容易覆盖,所以自己做一个类似的Node出来
var Node2 = function (node) {// 将要操作的结点传进去,然后返回一个对象,这个对象里给添加了有操作这个节点方法,所以对象.方法就可以实现操作了,而不需要mydom.addclass(item3,...)这样了
return{
getSiblings: function () {
var allSilings = node.parentNode.children;
var siblingsArray = {length:0};
for (let i = 0; i < allSilings.length; i++) {
if (allSilings[i]!==node){
siblingsArray[siblingsArray.length] = allSilings[i];
siblingsArray.length++;
}
}
return siblingsArray;
},
addClass:function (object) {
for (let key in object){
var methodName;
methodName = object[key] ? 'add':'remove';
node.classList[methodName](key);
}
}
}
}
let item4 = document.getElementById('item4');
var item4obj = Node2(item4);
console.log(' 方法二:');
console.log(item4obj.getSiblings());//测试成功
console.log(' 方法二:');
item4obj.addClass({a:true,xxx:false,c:true});
console.log(item4);//测试成功
// 改为jQuery
var jQuery = function (nodeOrSelector) {//将Node2改为jQuery,jQuery可以根据选择器去找到对应的元素
var node;
if(typeof nodeOrSelector==="string"){
node = document.querySelector(nodeOrSelector);
}else {
node = nodeOrSelector;
}
return{
getSiblings: function () {
var allSilings = node.parentNode.children;
var siblingsArray = {length:0};
for (let i = 0; i < allSilings.length; i++) {
if (allSilings[i]!==node){
siblingsArray[siblingsArray.length] = allSilings[i];
siblingsArray.length++;
}
}
return siblingsArray;
},
addClass:function (object) {
for (let key in object){
var methodName;
methodName = object[key] ? 'add':'remove';
node.classList[methodName](key);
}
}
}
}
let item5 = document.getElementById('item5');
var $item5 = jQuery(item5);
console.log(' 改为jQuery方法:');
console.log($item5.getSiblings());
console.log(' 改为jQuery方法:');
$item5.addClass({red:true,xxx:false,c:true});
console.log(item5);//测试成功
var child3 = jQuery('ul>li:nth-child(3)');
child3.addClass({blue:true});
// jQuery操作多个节点
var jQueryS = function (nodeOrSelector) {
var node = {};
if (typeof nodeOrSelector ==='string'){
var temp = document.querySelectorAll(nodeOrSelector);//先用querySelectorAll获取这个伪数组
for (let i = 0; i < temp.length; i++) {
node[i] = temp[i];
}
node.length = temp.length;//将伪数组净化,净化成只有0123值和length的伪数组
} else if(nodeOrSelector instanceof Node){// 如果是node,也将其转化成伪数组
node[0] =nodeOrSelector;
node.length = 1;
}
node.getSiblings = function () {
};
node.addClass = function (classesArray) {//传入class数组,给选择的多个节点都加上数组中class
classesArray.forEach(value=>{
for (let i = 0; i < node.length; i++) {
node[i].classList.add(value);
}
})
}
node.getTexts = function () {
var texts=[];
for (let i = 0; i < node.length; i++) {
texts.push(node[i].textContent);
}
return texts;
}
node.setTexts = function (text) {
for (let i = 0; i < node.length; i++) {
node[i].textContent = text;
}
}
//set和get合并
node.text = function (text) {
if (text===undefined){
var texts=[];
for (let i = 0; i < node.length; i++) {
texts.push(node[i].textContent);
}
return texts;
}else{
for (let i = 0; i < node.length; i++) {
node[i].textContent = text;
}
}
}
return node;
}
var allNodes = jQueryS('ul>li:nth-child(even)');//偶数孩子
allNodes.addClass(['big','green']);
console.log(allNodes.getTexts());
console.log(allNodes.text());
// console.log(allNodes.text(1));//测试成功
//总结:jQuery的作用就是将选择其选择的元素放到一个对象里,这个对象里有01234标序,代表每一个选择的元素,有length代表所有元素加起来总共的长度,有各种方法,addclass,gettext等等.就是反悔了这样一个hash
};
UseJquery.js
var $nodes = $('ul>li:nth-child(even)');//注意$nodesjQuery声明的变量前面要加一个$,防止混淆,因为jQuery声明的变量只能用jQuery的api,不能用dom的api.
console.log($nodes);
x.onclick = function () {
$nodes.toggleClass('pink');//toggle,开关,切换
// console.log(1);
}
var colorArray = ['blue','yellow','red','pink','big']
var $nodes2 = $('#ol2>li');
$nodes2.addClass(function (index,currentClass) {
return colorArray[index];//ol里面的每一个li加了'blue','yellow','red','pink','big'这几个属性
})
//https://www.jquery123.com/addClass/
3.this
和 arguments
f.call(asThis, input1,input2)
其中 asThis
会被当做 this
,[input1,input2] 会被当做 arguments
禁止使用 f(input1, input2)
,因为学会 .call
才能理解 this
this
和 arguments
function f(){
'use strict'
console.log(this)
console.log(arguments)
return undefined
}
f.call(1,2,3) // this 为 1,arguments 为 [2,3]
this 的值到底是什么?一次说清楚---方应杭
this定义:this是call的第一个参数.
this定义:this是call的第一个参数.
this定义:this是call的第一个参数.
「每日一题」JS中的闭包是什么?---方应杭
关于原型链:
「每日一题」什么是 JS原型链?---方应杭
JavaScript 世界万物诞生记
dom就是一个命名的空间,命名的所属对象
函数库:特定种类的API
jQueryMobil已经过时,不要学
jQuery的原型
测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js"></script>
<script>
console.log($.prototype)
console.log($.prototype.__proto__)
console.log($.prototype.__proto__ === Object.prototype)//继承自Object
</script>
</head>
<body>
</body>
</html>
结果如下:
就像Boolea,Array一样,
他的原型就是jQuery.prototype
总结:自己实现jquery例子
var myjQueryS = function(node){
var Node = {}
Node.length = 0
if((typeof node)==='string'){
var nodearr = document.querySelectorAll(node)
for (let index = 0; index < nodearr.length; index++) {
let element = nodearr[index];
Node[index] = element
Node.length++
}
}else{
Node['0'] = node
Node.length++
}
Node.addClass = function(addclass){
for (let index = 0; index < Node.length; index++) {
let element = Node[index]
element.classList.add(addclass)
}
}
Node.text = function(text){
if(text===undefined){
let textArr = []
for (let index = 0; index < Node.length; index++) {
let element = Node[index]
textArr.push(element.textContent)
}
return textArr
}else{
for (let index = 0; index < Node.length; index++) {
let element = Node[index]
element.textContent = text
}
}
}
return Node
}
var $div = myjQueryS('div')
console.log($div)
$div.addClass('xxx')
console.log($div.text())
// $div.text('xxx')