preface
- In this section, the DOM code encapsulated in the previous section is repackaged in jQuery style
- JQuery is very simple
Repackage in jquery-style
You’re probably saying to yourself a lot in this class: Why didn’t I think of that? !
The preparatory work
The preparation of each section is similar, and you can use it slowly
Create the project directory dom-2 > SRC > index.html, main.js, jquery.js
index.html
<! DOCTYPEhtml>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Writing jQuery</title>
</head>
<body>hello<script src="jquery.js"></script>
<script src="main.js"></script>
</body>
</html>
Copy the code
jquery.js
// Declare window.jQuery to be a function (? ! Never mind why it's a function.)
window.jQuery = function () {
console.log(` I'm jQuery `)}Copy the code
main.js
jQuery() // window. JQuery () // output: I'm jQuery
Copy the code
Enabling local Services
yarn global add parcel
parcel src/index.html
Copy the code
Chain style ❤️
Take a look at what code we are going to implement 👇
Also called jQuery style
- Window.jquery () is the global function we provide
Special function jQuery
JQuery (selector)
Used to get the corresponding element- But it does not return these elements
- Instead, it returns an object, called the object constructed by jQuery (the API in the handwritten DOM from the previous section)
- This object can manipulate the corresponding element
- Don’t understand? Straight to the code!
Code ⭕ ️
index.html
<body>
<div class="test">Hello 1</div>
<div class="test">Hello 2</div>
<div class="test">Hello 3</div>
<script src="jquery.js"></script>
<script src="main.js"></script>
</body>
Copy the code
jquery.js
// Declare window.jQuery to be a function (? !). (Never mind why it's a function)
window.jQuery = function (selector) {
const elements = document.querySelectorAll(selector) // Get all the elements of the selector (get an array)
// return elements
// General operation: just return the element found through the selector.
// But jQuery does something unusual: instead of returning an element, jQuery returns an API that can manipulate that element
/ / is as follows:
// The API can operate elements
// The API is an object that contains various functions that operate on elements.
// For example, addClass is the function that adds the class name to elements
const api = {
// Access variables outside the function. This is called a closure.
addClass(className) {
// Elements are variables outside the function addClass
for (let i = 0; i < elements.length; i++) { // Iterate over all the obtained elements and add the class name
elements[i].classList.add(className)
}
// return null
return api // the method still returns the API, which in turn contains many methods that can be called through the return value. addClass forms a chain 📌
// This is the chain style 📌}}return api
}
Copy the code
main.js
const api = jQuery(".test") // The element is retrieved from the selector, but is not returned
// Instead, it returns an API object containing a number of methods that can control the element
// console.log(api.addClass)
// Iterate over all the elements and add the.red class name
api.addClass("red").addClass('blue')
// The return value of the api.addClass method is still API, so the call can continue through the return value
Copy the code
1️ one
The following change in return must be understood
Return SAO operation 1️ one
Use this instead of API
window.jQuery = function (selector) {
const elements = document.querySelectorAll(selector) // Get all the elements of the selector (get an array)
const api = {
addClass(className) {
for (let i = 0; i < elements.length; i++) {
elements[i].classList.add(className)
}
// return api
return this
/* * This is the same as the previous object * obj.fn(p1); ↓ * obj.fn. Call (obj, p1); AddClass ("red") => This is the API when obj * is called. AddClass ("red") => Similarly, in addClass this is the API. Return this *; return this *; return this *; return this *; return this *; return this *}}return api
}
Copy the code
Return SAO operation 2️ one
Remove the API from jQuery completely
- Since we created the API object and then returned the API object, can’t we just return the object and omit the ASSIGNMENT part of the API?
- Would it not be “redundant”
window.jQuery = function (selector) {
const elements = document.querySelectorAll(selector)
const api = { // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
addClass(className) {
for (let i = 0; i < elements.length; i++) {
elements[i].classList.add(className)
}
return this}}return api // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
// omit the API assignment link 👇
window.jQuery = function (selector) {
const elements = document.querySelectorAll(selector) // Get all the elements of the selector (get an array)
// const api = {
return {
addClass(className) {
for (let i = 0; i < elements.length; i++) {
elements[i].classList.add(className)
}
return this}}// return api
}
Copy the code
The core idea of jQuery
The first core point: closures
- A jQuery function that receives a CSS selector
- Using the selector, we get the element Elements (but don’t return it), which returns an object
- The object returned contains many functions. These functions can operate on elements
Principle:
- Use “closures” to maintain elements
- Because the addClass function is accessing Elements. Accessed variables are not simply recycled by the browser
- This is one of the core ideas of jQuery
Second core point: chain operation
- AddClass, you can guess: when the user calls addClass, it must pass
JQuery (selector)
Get the API to call - That’s why I boldly return this.
- The addClass function wants to return whatever comes before the dot
api.addClass("red")
- So basically, the API goes from the front of addClass to the back of addClass, so you can call addClass
👇 API. The addClass (" red ") 👇. AddClass (" blue ")
- This is called chain operation.
JQuery code variant 2️ one
Main.js simplifies calls
Get rid of the variable x
const x = jQuery(".test") // Declare x, then use it directly. That assignment, that's redundant
x.addClass("red").addClass('blue').addClass('green')
// 👇 is eventually written as 👇
jQuery(".test").addClass("red").addClass('blue').addClass('green')
Copy the code
A small summary
- Advanced front-end code eliminates all intermediate processes
- Cut out all the things that don’t matter
- The result is the most concise code with the least information
- Although the code is extremely concise and elegant, it is simply incomprehensible to learners. (Note that “source code” is really not suitable for learners)
Is jQuery a constructor?
At this point you may have this question 👆
Constructors: ① before the new, ② to construct the object
- Combining these two characteristics, you can think of jQuery as a constructor or not
is
- Because the jQuery function does construct an object
not
- You don’t need to write new jQuery() to construct an object
- All of the previous constructors have to combine new
conclusion
- JQuery is a constructor that doesn’t need to add new
- JQuery is not a constructor in the normal (strict) sense
- This is because jQuery uses a few tricks (not necessary at this point, but confusing for beginners)
The term
Oral agreement 👄
The jQuery function returns an object called an object constructed by jQuery (the API in the original code).
Oral agreement:
- When we talk about jQuery objects, we will refer to objects constructed by jQuery functions.
- I’m not saying “jQuery this object”
- Make sure you remember
Other examples
- Object is a function
- Object, which represents the Object constructed by the Object constructor (not Object itself is an Object)
- Array is a function
- Array object/Array object, representing the object constructed by Array (not Array itself is an object)
- Function is a Function
- Function object/Function object, representing the object constructed by Function (not Function itself is an object)
More versatile packages ⭕️
The chain style
check
jQuery('#xxx') The return value is not an element, but an API object
jQuery('#xxx').find('.red') // Look for the.red element in # XXX
jQuery('#xxx').parent() // Get dad
jQuery('#xxx').children() // Get the son
jQuery('#xxx').siblings() // Get brothers
jQuery('#xxx').index() // Get the ranking number (starting from 0)
jQuery('#xxx').next() // Get the brother
jQuery('#xxx').prev() // Get the elder brother
jQuery('.red').each(fn) // Iterate over and perform fn on each element
Copy the code
code
window.jQuery = function (selectorOrArray) {
/* * elements always represents a collection of the selector's target elements * */
let elements
if (typeof selectorOrArray === "string") { / / overloaded
elements = document.querySelectorAll(selectorOrArray)
} else if (selectorOrArray instanceof Array) {
elements = selectorOrArray
}
// 👇 returns the object API constructed by the jQuery function.
return {
addClass(className) {
for (let i = 0; i < elements.length; i++) {
elements[i].classList.add(className)
}
return this
},
find(selector) {
let array = []
for (let i = 0; i < elements.length; i++) {
array = array.concat(Array.from(elements[i].querySelectorAll(selector)))
}
return jQuery(array) // <<<<<<<< focus on the following statement:
},
oldApi: selectorOrArray.oldApi,
end() {
return this.oldApi
},
each(fn) {
for (let i = 0; i < elements.length; i++) {
fn.call(null, elements[i], i, elements) // Iterate over each item, executing some method on each item
}
return this
},
print() {
console.log(elements)
return this
},
parent() {
const array = []
this.each(node= > {
if (array.indexOf(node.parentNode) === -1) { / / to heavy
array.push(node.parentNode)
}
})
array.oldApi = this
return jQuery(array)
},
children() {
const array = []
this.each(node= > {
if(node.children) { array.push(... node.children)// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
})
array.oldApi = this
return jQuery(array)
},
/ * * * * * * * * * * * * * * * * * * * * * the following is not mentioned in front of the * * * * * * * * * * * * * * * * * * * * * /
/* siblings() index() next() prev() */}}Copy the code
practice
/*
1
2
3
*/
window.jQuery = function(selectorOrArray){
let elements
if(typeof selectorOrArray === 'string'){
elements = document.querySelectorAll(selectorOrArray)
}else if(selectorOrArray instanceof Array){
elements = selectorOrArray
}
return {
addClass(className){
this.each(n= >n.classList.add(className))
},
find(selector){
let array = []
this.each(n= >{ array.push(... n.querySelectorAll(selector)) })return jQuery(array)
},
each(fn){
for(let i=0; i<elements.length; i++){ fn.call(null, elements[i], i)
}
}
}
}
window$=window.jQuery
$('#test').find('.child').addClass('red') // Please make sure this sentence is executed successfully
Copy the code
increase
Just a quick thought
code
// A quick review of dom node creation 👇 (two ways)
const div = document.createElement('div') // ① Pass in the label name
template.innerHTML = '<div></div>' / / (2) to HTML structure, and finally returned to the template. The content. firstChild
Copy the code
window$=window.jQuery = function(selectorOrArrayOrTemplate) {
let elements;
if (typeof selectorOrArrayOrTemplate === "string") {
if (selectorOrArrayOrTemplate[0= = ="<") {
/ / create a div
elements = [createElement(selectorOrArrayOrTemplate)];
} else {
/ / div
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;
}
// Return the API created by jQuery
return{
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)); }},// ...}}// Create a div and insert it into the body
$('<div><span>1</span></div>').appendTo(document.body)
Copy the code
delete
The same logic as the DOM implementation
$div.remove()
$div.empty()
Copy the code
change
The same logic as the DOM implementation
$div.text(?) // If you pass an argument, you write it. If you don't pass an argument, you read it.
$div.html(?) // If you pass an argument, you write it. If you don't pass an argument, you read it.
$div.attr('title',?)// Read and write properties
$div.css({color: 'red'}) // write style // note that the method name is CSS
$div.addClass('blue')
$div.on('click', fn)
$div.off('click', fn)Copy the code
Pay attention to
- Most of the time, $div corresponds to multiple div elements
- Be sure to default $div to an array and iterate over it (every operation)
window.$ = window.jQuery
jQuery('#test') // Write it this way every time you use it Copy the code
What? You think jQuery is too long
- You are right
- JQuery is a hard word to spell (and case sensitive)
- How can I make jQuery shorter?
- Bash Alias Remember bash Alias, just add an alias
// Must be added at the end of the code
window.jQuery = function (selectorOrArray){... }window$=window.jQuery
Copy the code
- After that, using $anywhere is equivalent to using jQuery
- Also can save trouble 👇 again
window$=window.jQuery = function (selectorOrArray){... }// Write on one line from right to left
JQuery = function(){}
// Then assign the result of window.jQuery to window.$
Copy the code
- This is the way many advanced programmers write it