review
This article will focus on extending the functionality of the jQuery API to make it more powerful. This article will focus on extending the functionality of the jQuery API to make it more powerful.
The following is the code used in this exercise, based on the first article, using addClass() as an example.
<ul>
<li id="item1">item1</li>
<li id="item2">item2</li>
<li id="item3">item3</li>
<li id="item4">item4</li>
<li id="item5">item5</li>
</ul>
.red{
color:red;
}
window.simpleTools = function(node){
return{
addClass:function(classes){ classes.forEach((value) => node.classList.add(value)); }}; };Copy the code
Thought 1: What if the pass parameter is a selector?
Solution:
Add a type judgment to solve it! To make our code more semantic, rename the passed argument from node to nodeOrSelector, and define a node variable in the function. If the passed argument is a selector, use document.querySelector() to find the corresponding node and assign it to node. If the parameter is not a selector, assign it directly to Node and store it.
var node;
if(typeof nodeOrSelector === 'string'){
node = document.querySelector(nodeOrSelector);
}else{
node = nodeOrSelector;
}
Copy the code
Test run:
var nodeTest = simpleTools('#item3');
nodeTest.addClass(['red']);
console.log(document.querySelectorAll('#item3'));
Copy the code
Thought 2: What if the parameter is passed with multiple selectors?
Solution:
- the
document.querySelector( )
todocument.querySelectorAll( )
, the variable node becomes a Nodes object. - Iterate over Nodes and add red in order
window.simpleTools = function(nodeOrSelector){
var nodes = {};
if(typeof nodeOrSelector === 'string'){
nodes = document.querySelectorAll(nodeOrSelector);
}else{
nodes = nodeOrSelector;
}
return{
addClass:function(classes){
classes.forEach((value) =>{
for(var i = 0;i < nodes.length;i++){
nodes[i].classList.add(value);
}
});
}
};
};
Copy the code
Test run:
var nodeTest = simpleTools('ul>li');
nodeTest.addClass(['red']);
console.log(document.querySelectorAll('ul>li'))
Copy the code
var nodeTest2 = simpleTools('#item3');
nodeTest2.addClass(['red']);
console.log(document.querySelectorAll('#item3'))
Copy the code
Thought 3: What if you want to change the prototype chain?
Now nodes is an Object connected to Nodelist. prototype. I want my prototype chain to be object. prototype.
Solution:
With a temporary variable, loop through to get a pure object.
window.simpleTools = function(nodeOrSelector){
var nodes = {};
if(typeof nodeOrSelector === 'string'){
var temp = document.querySelectorAll(nodeOrSelector);
for(var i =0 ; i<temp.length; i++){ nodes[i] = temp[i]; } nodes.length = temp.length; }else if(nodeOrSelector instanceof Node){
nodes = {
0 :nodeOrSelector,
length :1
};
}
returnnodes; // Just look at the nodes changes, ignoring the addClass() method for now;Copy the code
If there are multiple selectors, traverse and save, and don’t forget nodes.length. If it’s a node, you also need to construct a nodeOrSelector to store it in the node object in the same form as the branch above. Now either multiple selectors or a node has been converted to link object.prototype only.
Test run:
var nodeTest = simpleTools('#item3');
console.log(nodeTest);
Copy the code
var nodeTest2 = simpleTools('ul>li');
console.log(nodeTest2);
Copy the code
Thought 4: How to set the text?
To get text, store the textContent for each item in Nodes.
getText : function(){
var texts = [];
for(var i = 0; i < nodes.length; i++){ texts.push(nodes[i].textContent); }return texts;
}
Copy the code
If it is set text, the text to be set is assigned to textContent in turn by iterating through.
setText : function(text){
for(var i = 0; i < nodes.length; i++){ nodes[i].textContent = text; }return text;
}
Copy the code
Test run:
var nodeTest = simpleTools('#item3');
nodeTest.setText('hello');
Copy the code
Code optimization
The code above looks so similar, both in setup and fetch, that there is potential for optimization. We’re trying to combine these two functions into one, so if you pass in arguments, you need to set text, and if no arguments are passed in, you want to get text.
text: function (text) {
if (text == undefined) {
var texts = [];
for (var i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent);
}
return texts;
}
else {
for(var i = 0; i < nodes.length; i++) { nodes[i].textContent = text; }}}Copy the code
Give me another alias
window.$ = function simpleTools() {... }Copy the code
Using the global variable $is equivalent to using simpleTools.
If a variable is constructed from jQuery, add a $before the variable to prevent confusion.
Eg: Var $node = $(#item3)
Two forms of return
The first kind of
window.$ = function simpleTools(nodeOrSelector) {
var nodes = {};
if (typeof nodeOrSelector === 'string') {
var temp = document.querySelectorAll(nodeOrSelector);
for (var i = 0; i < temp.length; i++) {
nodes[i] = temp[i];
}
nodes.length = temp.length;
} else if (nodeOrSelector instanceof Node) {
nodes = {
0 : nodeOrSelector,
length: 1
};
}
return {
addClass: function(classes) {
classes.forEach((value) =>{
for(var i = 0; i < nodes.length; i++) { nodes[i].classList.add(value); }}); }, text:function(text) {
if (text == undefined) {
var texts = [];
for (var i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent);
}
return texts;
} else {
for(var i = 0; i < nodes.length; i++) { nodes[i].textContent = text; }}}}; };Copy the code
The second,
window.$ = function simpleTools(nodeOrSelector) {
var nodes = {};
if (typeof nodeOrSelector === 'string') {
var temp = document.querySelectorAll(nodeOrSelector);
for (var i = 0; i < temp.length; i++) {
nodes[i] = temp[i];
}
nodes.length = temp.length;
} else if (nodeOrSelector instanceof Node) {
nodes = {
0 : nodeOrSelector,
length: 1
};
}
nodes.addClass = function(classes) {
classes.forEach((value) =>{
for(var i = 0; i < nodes.length; i++) { nodes[i].classList.add(value); }}); }; nodes.text =function(text) {
if (text == undefined) {
var texts = [];
for (var i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent);
}
return texts;
} else {
for(var i = 0; i < nodes.length; i++) { nodes[i].textContent = text; }}};return nodes;
};
Copy the code
You may choose whichever you like
summary
- AddClass () extends its addClass() method to not only pass nodes, but also accept selectors.
- Further deepen the understanding of the prototype chain.
Try writing your own API!