jQuery Selector (Basic Edition)

Keywords: Javascript JQuery

For jQuery calls, we typically pass in parameters

  html: <div></div>
  js: console.log($('<a />'));
    console.log($('div'));

1. Preposition (DOM object and jQuery object)

  1. DOM objects,
    This should be the basic knowledge of the front end. In the document object model, each part is a node.
  2. jQuery object
    This refers to the object created by the jQuery constructor, which can be retrieved by the jQuery selector and stored in jQuery as an array of classes.

II. Practice

Looking at the returned jQuery object carefully, it feels like encapsulating the DOM node and saving it on jQuery

1. Implementing a Basic Creation Selector
  1. Get the incoming parameters and decide whether to create a jquery node or a query node.
  2. Create a new node and pass in an html tag for judgment
     //Get the incoming parameters
     var jQuery = function(selector, content) {
       return new jQuery.prototype.init(selector, content);
     }
     jQuery.prototype = {
         length: 0,
         init: function(selector, content) {
           content = content || document;
           var match; //match is used to save selector;
           if(typeof selector === 'string') {
             // Judging that the selector passed in an html tag;
             if(selector.charAt(0) === '<' && selector.charAt(selector.length-1) === '>' && selector.length >= 3 ) {
               match = [selector];
             }
             if (match) {
               //Create a jQuery object.
             }
           }
         }
       } 
  1. Once we have determined that we need to create a node, we need to think about what we need to do. You need to parse the label name, then create the node using createElement, and save it.
    • Define an html analytic function
    var reg = /^<(\w+)\s*\/?>(?:<\/\1>|)$/;
    jQuery.extend({
         parseHtml: function(data, content) {
           if (!data && typeof data != 'string') {
             return null;
           }
           var parse = reg.exec(data);
           return [content.createElement(parse[1])] //ok, here is to save the entire DOM node created in an array.
         }
    })
    • Now that the created node is available, you can mount the node on jQuery.
    if(match) {
         for(; i < match.length; i++) {
           var opt = match[i]
           this[i]=jQuery.parseHtml(opt, content)[i]
         }
    }

    Okay, now we can see the results of the code execution.

    ok, barely, but it still seems a bit wrong. Let's take a look at the source code of jQuery.

    You can see that the merge method was called. Jump to the merge method for a look. Generally speaking, merge is used to merge two arrays, and it can also be used to combine numbers on objects with length attributes.

    // push.apply(_, arraylike) throws on ancient WebKit
    
    merge: function (first, second) {
        var len = +second.length,
          j = 0,
          i = first.length;
        for (; j < len; j++) {
          first[i++] = second[j];
        }
        first.length = i;   
        return first;
    }
    Understanding the difference, let's optimize the code.
  2. optimization

2. Implementing a basic label selector
  1. DOM native node query
    • document.querySelector
    • document.querySelectorAll// Returns a NodeList
  2. practice
    Use document to find nodes natively, get results, and then put each on jQuery
     var ele, i = 0;
     if(match) {}
     else {
         ele = document.querySelectorALL(selector);
         for(; i < ele.length; i++) {
           this[i] = ele[i]
         }
         this.length = ele.length;
     }
3. A selector for passing in a method
  1. First, look at how init handles:
  var rootjQuery;
  init = jQuery.fn.init = function(selector, context, root) {
    ...
    root = root || rootjQuery;
    if(typeof selector === 'string') {
      ...
    } else if (isFunction(selector)) {
      return root.ready !== undefined ? root.ready(selector) : selector(jQuery);
    }
  }
  rootjQuery = jQuery(document);

As you can see from the code, js can actually pass three parameters, and root defaults to document. If root. read has no initial, it immediately executes the incoming method, otherwise it calls the root. read method. As far as root is concerned, as you can see from the code, it's global, so root.ready == jQuery.ready.

  1. Before looking at the read method, we need to make it clear that the processing of the jquery input method is performed after the document is loaded, so we should first judge whether the document is loaded or not.
    function completed() {
      document.removeEventListener('DOMContentLoaded',completed);
      window.removeEventListener('load', completed);
      jQuery.ready();
    }
    
    if(document.readyState === 'complete' || (document.readyState !== "loading" && !document.documentElement.doScroll)) {
      window.setTimeout(jQuery.ready);
    } else {
      //When the dom is loaded, call complate to remove the listening event.
      document.addEventListener('DOMContentLoaded', complete);
      window.addEventListener('load', completed);
    }
  1. See the jQuery. read method.
  jQuery.extend({
    // If DOM is ready for use and changes, it will be changed to true.
    isReady: false,
    //Number of Items to Wait Before Tracking Ready Events Trigger
    readyWait: 1,
    ready: function(wait) {
      if(wait === true ? --jQuery.readyWait : jQuery.isReady) {
        return ;
      }
      //DOM nodes are ready
      jQuery.isReady = true;
      
      if(wait !== true && --jQuery.readyWait > 0) {
        return 
      }
      //If there is a function binding, execute it immediately.
      readyList.resolveWidth(document, [jQuery])
    }
  })

From 2. we can see that when the DOM node is loaded, a ready call is made, and no wait is passed in. The first judgment in the read is skipped directly and jQuery.isReady = true is recorded. Then we can see the next sentence and call the readyList.resolveWidth method. At this time, the DOM node is loaded and the binding function can be executed. Counting,
What is this readyList? Let's look it up in the code.

   var readyList = jQuery.Deferred();

   jQuery.fn.ready = function(fn) {
     ready.then(fn).catch(error) {
       jQuery.readyException(error);
     }
     return this;
   }

As can be seen from the above code, readyList is the return value of the Deferred function, and from the call below, it can be inferred that the Defferred function should be a promise object. For the Defferred function, we'll look at it carefully next time.
Now let's review the whole function flow:

The above content is only my own understanding, if there is anything wrong, I hope you can help point out ah!

Posted by mdj on Mon, 09 Sep 2019 01:53:26 -0700