Warm prompt

If you have not learned or forgotten JavaScript operations, please check out ruan Yifeng’s JavaScript tutorial.

Introduction:

DOM has many apis, but some of them are too difficult to use. For example, what about all the brothers who want to get an element? For example, if I want to add more classes to an element, say node.classlist.add (). What if I want to add 100? You can’t write it 100 times, so you can package an API.

Learn from the bigwigs

How to do jQuery, let’s imitate it. There are many functions in the jQuery library, such as addClass(),.css(),.data(), and so on. In other words, jQuery is a big warehouse of tools that we use when we need them. Now what we do is, we make a lot of tools ourselves, and then we build our own warehouse, and we take whatever we want out of the warehouse.

1. Production tools

Suppose we now need two tools, one to get a sibling element and the other to add classes.

Realize the function

1. Get the sibling Element

Operation steps:

  1. In HTML there is a UL tag, and in UL there are five Li’s.
<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>
Copy the code
  1. Gets the sibling element with ID item3. Start by defining an allChildren variable to store all the child elements of the parent of Item3. There are two apis for retrieving child DOM elements, Node.parent. Children and Node.parent. ChildNodes. Which one should I choose?

    Parent. ChildNodes: Obtains nodes. Different browsers perform different operations.

IE: get element nodes only;

Non-ie: get element nodes and text nodes;

Parent. Children: Gets the element node, the browser behaves the same.

Therefore, children is recommended.

var allChildren = item3.parentNode.children;
Copy the code

  1. Define an empty array to hold sibling elements with length 0.
var arr = {length:0};
Copy the code
  1. Iterate over all of the child nodes, if not item3, into the ARR array.
for(var i = 0; i < allChildren.length; i++){if(allChildren[i] !== item3){
    arr[arr.length] = allChildren[i];
    arr.length++;
  }
}
Copy the code

Tip: use arr[arr.length] = allChildren[I]; Causes array subscripts to store item elements in sequence.

Complete code:

<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>

var allChildren = item3.parentNode.children;
var arr = {length:0};

for(var i = 0; i < allChildren.length; i++){if(allChildren[i] ! == item3){ arr[arr.length] = allChildren[i]; arr.length++; } } console.log(arr);Copy the code

Running results:

Note: This arR Array is a pseudo-array. Its prototype chain points directly to Object, not array. prototype. There is no array.push () method if the prototype chain does not contain array.prototype.

Encapsulate as a function

  1. Let’s wrap it up and call it function and give it a name so it’s easy to call.
function getSiblings(){
  var allChildren = item3.parentNode.children;
  var arr = {length:0};
  for(var i = 0; i < allChildren.length; i++){if(allChildren[i] ! == item3){ arr[arr.length] = allChildren[i]; arr.length++; } } console.log(arr); }Copy the code
  1. We’re going to give this function a return value, and the return value is this arrayconsole.log(arr)toreturn arr
  2. Item3 is the external value of the function and can only be obtained by passing the parameter when calling the function. Therefore, add a parameter to our function and change item3 to parameter node.
function getSiblings(node){
  var allChildren = node.parentNode.children;
  var arr = {length:0};
  for(var i = 0; i < allChildren.length; i++){if(allChildren[i] !== node){
      arr[arr.length] = allChildren[i];
      arr.length++;
    }
  }
  return arr;
}
console.log(getSiblings(item3)); 
Copy the code

2. Add multiple classes

The operation process is the same as above, only the code and necessary explanation are given here.

Functions:

<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>

var classes = {'a':true.'b':false.'c':true}
for(var key in classes){
  var value = classes[key];
  if(value){
    item3.classList.add(key);
  }
  else{ item3.classList.remove(key); }}Copy the code

Hash the added class, if true, to Item3, if false, to remove it.

Encapsulate as a function:

function addClasses(node,classes){
  for(var key in classes){
    var value = classes[key];
    if(value){
      node.classList.add(key);
    }
    else{
      node.classList.remove(key);
    }
  }
}
addClasses(item3,{'a':true.'b':false.'c':true}); // The parameters passed in include the node and the class to be addedCopy the code

Optimization and finishing:

function addClasses(node,classes){
  for(var key in classes){
    var value = classes[key];
    var methodName = value ? 'add':'remove';
    node.classList[methodName](key);
  }
}
addClasses(item3,{'a':true.'b':false.'c':true});
Copy the code

To clarify, we decide whether to add this class based on whether the key passed in is true or false. node.classList.add(key); And the node. The classList. Remove (key); Is a class of code, the difference is to call the add method or remove method, then there is the possibility of optimization. Define a methodName variable that holds the value, which is true or false for each iteration of the loop. Let node.classList[methodName](key) call methodName directly each time. Note: If you only know the object obj.add() call and don’t understand the obj[]() call method, review JavaScript basics.

Running results:

2. Build a warehouse to store tools

Now that our tools are finished, it is time to build a house for tools. The jQuery tool house is called jQuery, so let’s take a name of our own, for example, my name is simpleTools.

window.simpleTools = function() {return{
    getSiblings:function(){},
    addClass:function(){}
  };
};
Copy the code

Window.simpletools is our big house, which is a function house with getSiblings and addClass objects inside, which is like a tool shelf. Next, we put the functions encapsulated above on the corresponding shelves.

window.simpleTools = function(node){
 return{
   getSiblings:function(){
    var allChildren = node.parentNode.children;
    var arr = {length:0};
    for(var i = 0; i < allChildren.length; i++){if(allChildren[i] !== node){
        arr[arr.length] = allChildren[i];
        arr.length++;
      }
    }
    return arr;
   },
   addClass:function(classes){
     for(var key in classes){
      var value = classes[key];
      var methodName = value ? 'add':'remove'; node.classList[methodName](key); }}}; };Copy the code

The Node that passes to function is like our little warehouse steward. Once it’s called to work (with parameters coming in), it goes to each tool and tells it to be ready to go.

Now add a few test statements and see what happens.

var nodeTest = simpleTools(item3);
console.log(nodeTest.getSiblings());
nodeTest.addClass({'a':true.'b':false.'c':true});
Copy the code

Running results:

Good, same results as before, which means we didn’t have a bug from putting it in the repository.

summary

So far, you’ve learned to write your own warehouse. Let’s review the process again.

Production tools:

  1. Realize the function
  2. Encapsulate as a function
  3. Appropriate optimization

Building warehouse tools:

  1. Build a warehouse
  2. In the tool

Quick start to implement a warehouse of their own bar, the code of follow-up optimization see from the package function to the implementation of simple version of their own jQuery (2).