Simple implementation of jQuery principle series css selector

  • 2021-06-28 08:34:44
  • OfStack

The most powerful feature of jQuery is that it can find elements through the css selector. Half of its source code is the code of the sizzle css selector engine. After the html5 specification was introduced, document.querySelector and document.querySelectorAll were added to find elements directly. If you are doing mobile development, the need to use jQuery was greatly reduced.

To implement the css selector with js code, regular expressions must be used to recognize strings. Of course, native api provided by browsers is more efficient. The following code only demonstrates the principles and does not give priority to performance.

for example

1) Finding id is obviously more efficient with document.getElementById, the browser has made hash, and once-found elements do not have to traverse every node.

2) Finding name is more efficient with document.getElementsByName, which the browser has made a collection containing.

3) Finding tag names is more efficient with document.getElementsByTagName. The browser has made a collection containing this tag. Finding a subset from this collection can obviously traverse a lot less elements. Whether the browser updated the cached collection at the time of element creation is unknown.However, contains can also be a performance penalty in determining whether or not a child node of the target element is required from this collection.

Okay, let's ignore the problem of using native api optimal selectors and just use pure regular expressions to make a simple implementation. First, use regular expressions to judge if #is the id selector, if # is the class selector, if [] is the attribute selector, set the search target, and then start traversing the child nodes.To iterate through the id, name, className, getAttribute of an childNodes subnode using a recursive function, return the element if it matches.The complete code is as follows:

html:


<body>
  <div>
    
    <span id="sp_id">hello,id</span>
    <span class="sp_class">hello,class</span>
     <span name="sp_name" >hello,name</span>
     <b>hello,tag</b>
  </div>
 </body>

javascript:


<script type="text/javascript">
   
   
   function find(el, selector) { // Find child nodes, similar in usage jquery Of find Function, only supported id,class,attr Selector, only supports returning matching first 1 Elements 
    var m = selector.match(/([#\.\[])([\w\W]+)/i);
    var type, key,attrName, result;
    if (m) {
      if (m[1] == ".") {
        type = "class"; key = m[2];
      } else if (m[1] == "#") {
        type = "id"; key = m[2];
      } if (m[1] == "[") {
        type = "attr";
        m = m[2].match(/(\w+)=(\w+)/i);
        attrName = m[1];
        key = m[2];
      }
    } else {
      type = "tag"; key = selector;
    }
    
    function findChild(node) {
      var c;
      for (var i = 0; i < node.childNodes.length; i++) {
        c = node.childNodes[i];
        if (type == "class" && c.className == key) {
          result = c;
          return;
        } else if (type == "id" && c.id == key) {
          result = c;
          return;
        } else if (type == "attr" && c.getAttribute && c.getAttribute(attrName) == key) {
          result = c;
          return;
        } else if (type == "tag" && c.tagName && c.tagName.toLowerCase() == key) {
          result = c;
          return;
        }
        findChild(c);
      }
    }
    findChild(el);
    return result;
    
  }
  
  console.log(find(document.body,"#sp_id").innerHTML);
  console.log(find(document.body,".sp_class").innerHTML);
  console.log(find(document.body,"[name=sp_name]").innerHTML);
  console.log(find(document.body,"b").innerHTML);
    
  </script>

Related articles: