I’ll use this article to explain a simple way to encapsulate jQuery with JS.

At the end of the complete code link, code needs to see the end of the friends directly

In this article, JS implements the following jquery methods, which I’ve broken down into eight small goals

  • Implement the $(“.box1”).click() method
  • Implement the $(“div”).click() method
  • Consider three cases of the argument in $()
  • Implement the ON method in JQ
  • Realize chain operation
  • Implement eq method in JQ
  • Implement the end method in JQ
  • Implement CSS methods in JQ
If there are any inaccuracies, please point them out in the comments section. Thanks.

Implement the $(“.box1”).click() method

First, let’s set our first small goal, which is how to implement the following jQuery code step by step.

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>// Delete the CDN from the same file<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
    <style>
        .box1 {
            width: 100px;
            height: 100px;
            background: red;
        }
    </style>
</head>
<body>
    <div class="box1"></div>
</body>
<script>
    $(".box1").click(() = >{
        console.log(456);
    })
</script>
</html>
Copy the code

The code address

If you don’t know how to use jQuery, don’t panic. As long as you have a little js foundation, take 10 minutes to learn about jQuery.

	$(".box1").click(() = >{
        console.log(456);
	})
Copy the code

All right, let’s analyze the jQuery code above.

  • $(“.box1”) implements the selector.
  • $(“.box1”).click is the selector + call the click method
  • Finally, pass the function inside click.

The first small goal is to encapsulate JS to achieve the functionality of the code above. We have a three-step strategy to achieve this.

  1. Js $(” box1 “)
  2. $(” box1 “). Click ()
  3. $(” box1 “). Click (() = > {the console. The log (” 123 “)})

The first step is to implement $(“.box1”) with JS, right

    // 实现$(".box1")
    class jquery {
        constructor(arg) {
            console.log(document.querySelector(arg)); }}function $(arg) {
        return new jquery(arg);
    }

    // 实现$(".box1")
    let res =  $(".box1");
    console.log(res);
Copy the code

This implements () by building () and returning jquery instance, and implements (“.box1”) by building () and returning jquery instance.

Ok, so step 2 is to implement $(“.box1”).click(). As you can see, there is a click method in the jquery class.

    / / $(" box1 "). Click ()
    class jquery {
        constructor(arg) {
            console.log(document.querySelector(arg));
        }

        click() {
            console.log("Execute click method"); }}function $(arg) {
        return new jquery(arg);
    }

    / / $(" box1 "). Click ()
    let res =  $(".box1").click();
    console.log(res);
Copy the code

Next, we in the third step is to implement the $(” box1 “). Click (() = > {the console. The log (” 123 “)}).

    $(".box1").click(() => {console.log("123")})
    class jquery {
        constructor(arg) {
            this.element = document.querySelector(arg);
            // console.log(element);
        }

        click(fn) {
            this.element.addEventListener("click", fn); }}function $(arg) {
        return new jquery(arg);
    }

    
    $(".box1").click(() => {console.log("123")})
    $(".box1").click(() = > {
        console.log("123")});Copy the code

So far, we have achieved the first small goal, do you think it is easy? Ok, let’s move on to the second small goal.

2. Implement $(“div”).click()

The second small goal is to consider multiple div elements that need to be bound to a click event. If we use selectSelectorAll to get the element, it’s actually quite simple to create an extra loop in the click method to get the value in NodeList. I’m going to go straight to the code, so you can try it out.

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
    <style>
        .box1 {
            width: 100px;
            height: 100px;
            background: red;
        }
        .box2 {
            width: 100px;
            height: 100px;
            background: blue;
        }
    </style>
</head>

<body>
    <div class="box1"></div>

    <div class="box2"></div>
</body>

<script>
    $(".box1").click(() => {console.log("123")})
    class jquery {
        constructor(arg) {
            // The following element stores the NodeList object, which is an array of classes with a length attribute
            this.element = document.querySelectorAll(arg);
        }

        click(fn) {
            for(let i = 0; i < this.element.length; i++) {
                this.element[i].addEventListener("click", fn); }}}function $(arg) {
        return new jquery(arg);
    }
 
    $(".box1").click(() => {console.log("123")})
    $("div").click(() = > {
        console.log("123")});</script>

</html>
Copy the code

The code address

Ok, now that you’ve accomplished two small goals, I believe you have a sense of accomplishment.

3. Consider three cases of the argument in $()

Next, let’s consider the case where the $() parameter is different. Let me list the three cases. (There may be other cases, but I won’t mention them here.)

1. Case 1: $() is a string

	$(".box1")
Copy the code

$() is a function.

	// Arguments are functions
	$(function() {
	console.log("123");
	})
Copy the code

3. Case 3: the node whose $() parameter is NodeList or selectSelect

	/ / is three
	$(document.querySelectorAll("div")).click(() = >{
		console.log("123"); $(})document.querySelector("div")).click(() = >{
		console.log("456");
	})
Copy the code

And then the third little goal is the handwriting function to implement three cases. First we add the addEles method and modify the click method above

        addEles(eles){
            for (let i = 0; i < eles.length; i++) {
                this[i] = eles[i];
            }
            this.length = eles.length;
        }


        $(".box1").click(() => {console.log("123")})
        click(fn) {
            for(let i = 0; i < this.length; i++) {
                this[i].addEventListener("click", fn); }}Copy the code

Next, three different parameter processing methods are implemented

        constructor(arg) {
    
            / / a
            if(typeof arg === 'string') {
                this.addEles(document.querySelectorAll(arg));
            }else if(typeof arg === 'function') {
                / / 2
                document.addEventListener("DOMContentLoaded", arg);
            }else {
                / / is three
                if(typeof arg.length === 'undefined') {
                    this[0] = arg;
                    this.length = 1;
                }else {
                    this.addEles(arg); }}}Copy the code

4. Implement the ON method in JQ

The fourth small goal is to implement the ON method of JQ

        / / on the way
        on(eventName, fn) {
            let eventArray = eventName.split("");
            // Consider multiple nodes
            for(let i = 0; i < this.length; i++) {
                // Consider multiple events
                for(let j = 0; j < eventArray.length; j++) {
                    this[i].addEventListener(eventArray[j], fn); }}}Copy the code

Let’s test it again

    / / on the way
    $("div").on("mouseover mousedown".function(){
        console.log("On way");
    })
Copy the code

5. Chain operation

Next, implement the fifth sub-goal to implement the chain operation of JQ

Add return this to on and click to create a chain

        // chain operation
        // Add return this to click and on
        / / click method
        click(fn) {
            for(let i = 0; i < this.length; i++) {
                this[i].addEventListener("click", fn);
            }
            return this; 
            // console.log(this);           
        }
    
        / / on the way
        on(eventName, fn) {
            let eventArray = eventName.split("");
            // Consider multiple nodes
            for(let i = 0; i < this.length; i++) {
                // Consider multiple events
                for(let j = 0; j < eventArray.length; j++) {
                    this[i].addEventListener(eventArray[j], fn); }}return this;
        }
Copy the code

6. Implement eq method in JQ

The sixth sub-goal is to implement the EQ method in JQ

        / / eq method
        eq(index) {
            return new jquery(this[index]);
        }
Copy the code

How to create a new jquery

  1. Executive function
  2. Automatically creates an empty object
  3. Points the empty object’s prototype to the constructor’s Prototype property
  4. Bind the empty object to the function’s internal this
  5. If renturn is followed by an object, return that object. This object is returned automatically if not followed

7. Implement the end method in JQ

Implement the seventh small goal implements the end method in JQ. To do this, in addition to adding the end() method, we need to add the constructor parameter root, the prevObject property, and the eq method parameter this.

        constructor(arg, root) {
            if(typeof root === "undefined") {
                this.prevObject = [document];
            }else {
                this.prevObject = root;
            }
        / / eq method
        eq(index) {
            return new jquery(this[index], this);
        }
        / / end method
        end() {
            return this.prevObject;
        }
Copy the code

8. Implement CSS methods in JQ

CSS can fetch styles in JQ and set one or more styles

// Get the style (just get the first element)

	let res =  $("div").css("background");
	console.log(res);

// Set the style

	$("div").css("background"."yellow");


// // Case 3 (Set multiple styles)

	$("div").css({background:"black".width:200.opacity:0.3});
Copy the code

Next, implement the CSS methods

        / / CSS method
        
        css(. args) {
            if(args.length === 1) {
                
                // Get the style
                if(typeof args[0= = ='string') {
                    return this.getStyle(this[0], args[0]);
                }else {
                    // Set multiple styles
                    for(let i = 0; i < this.length; i++) {
                        for(let j in args[0]) {
                            this.setStyle(this[i], j, args[0][j]); }}}}else {
                / / is three
                for(let i = 0; i < this.length; i++) {
                    this.setStyle(this[i], args[0], args[1]); }}}/ / CSS method
     css(. args) {
        if(args.length === 1) {
            // Get the style
            if(typeof args[0= = ='string') {
                return this.getStyle(this[0], args[0]);
            }else {
                // Set multiple styles
                for(let i = 0; i < this.length; i++) {
                    for(let j in args[0]) {
                         this.setStyle(this[i], j, args[0][j]); }}}}else {
            / / is three
            for(let i = 0; i < this.length; i++) {
                this.setStyle(this[i], args[0], args[1]); }}}Copy the code

Add the cssNumber method to determine the attribute name without adding PX

    / / CSS method
    $.cssNumber = {
        animationIterationCount: true.columnCount: true.fillOpacity: true.flexGrow: true.flexShrink: true.fontWeight: true.gridArea: true.gridColumn: true.gridColumnEnd: true.gridColumnStart: true.gridRow: true.gridRowEnd: true.gridRowStart: true.lineHeight: true.opacity: true.order: true.orphans: true.widows: true.zIndex: true.zoom: true
}
Copy the code

Finally, the complete code, if the big brothers feel good, give a thumbs up

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
    <style>
        .box1 {
            width: 100px;
            height: 100px;
            background: red;
        }
        .box2 {
            width: 100px;
            height: 100px;
            background: blue;
            transform-origin: 0 100% 0;
            transition: 0.3 s;
            
        }
        .box2:hover {
            transform: scaleX(2);
            width: 200px;
            height: 100px;
        }
    </style>
</head>

<body>
    <div class="box1"></div>

    <div class="box2"></div>
    <button>Click on the</button>
</body>

<script>
    
    class jquery {

        constructor(arg, root) {
            if(typeof root === "undefined") {
                this.prevObject = [document];
            }else {
                this.prevObject = root;
            }
            / / a
            if(typeof arg === 'string') {
                this.addEles(document.querySelectorAll(arg));
            }else if(typeof arg === 'function') {
                / / 2
                document.addEventListener("DOMContentLoaded", arg);
            }else {
                / / is three
                if(typeof arg.length === 'undefined') {
                    this[0] = arg;
                    this.length = 1;
                }else {
                    this.addEles(arg); }}}// Add methods
        addEles(eles){
            for (let i = 0; i < eles.length; i++) {
                this[i] = eles[i];
            }
            this.length = eles.length;
        }

        // chain operation
        // Add return to click and on
        / / click method
        click(fn) {
            for(let i = 0; i < this.length; i++) {
                this[i].addEventListener("click", fn);
            }
            return this; 
            // console.log(this);           
        }

        / / on the way
        on(eventName, fn) {
            let eventArray = eventName.split("");
            // Consider multiple nodes
            for(let i = 0; i < this.length; i++) {
                // Consider multiple events
                for(let j = 0; j < eventArray.length; j++) {
                    this[i].addEventListener(eventArray[j], fn); }}return this;
        }

        / / eq method
        eq(index) {
            return new jquery(this[index], this);
        }

        / / end method
        end() {
            return this.prevObject;
        }

        / / CSS method
        css(. args) {
            if(args.length === 1) {
                
                // Get the style
                if(typeof args[0= = ='string') {
                    return this.getStyle(this[0], args[0]);
                }else {
                    // Set multiple styles
                    for(let i = 0; i < this.length; i++) {
                        for(let j in args[0]) {
                            this.setStyle(this[i], j, args[0][j]); }}}}else {
                / / is three
                for(let i = 0; i < this.length; i++) {
                    this.setStyle(this[i], args[0], args[1]); }}}getStyle(ele, styleName) {
            return window.getComputedStyle(ele, null)[styleName];
        }
        setStyle(ele, styleName, styleValue) {
            if(typeof styleValue === "number" && !(styleName in $.cssNumber)) {
                styleValue = styleValue + "px"; } ele.style[styleName] = styleValue; }}function $(arg) {
        return new jquery(arg);
    }
 
    / / CSS method
    $.cssNumber = {
        animationIterationCount: true.columnCount: true.fillOpacity: true.flexGrow: true.flexShrink: true.fontWeight: true.gridArea: true.gridColumn: true.gridColumnEnd: true.gridColumnStart: true.gridRow: true.gridRowEnd: true.gridRowStart: true.lineHeight: true.opacity: true.order: true.orphans: true.widows: true.zIndex: true.zoom: true
}
    // // Implementation 1: $(".box1")
    // $("div").click(() => {
    // console.log("123")
    // });

    // // Implementation case 2: Parameters are functions
    // $(function() {
    //     console.log('情况2');
    // })

    // // Case three
    // $(document.querySelectorAll("div")).click(()=>{
    // console.log("123");
    // })
    // $(document.querySelector("div")).click(()=>{
    // console.log("456");
    // })

    // // on method
    // $("div").on("mouseover mousedown",function(){
    // console.log("on method ");
    // })

    // chain operation
    // $("div").click(() => {
    // console.log("click method ")
    // }).on("mouseover", function() {
    // console.log(' chained on method ');
    // })

    // $("div").on("mouseover", function() {
    // console.log(' chained on method ');
    // }).click(() => {
    // console.log("click method ")
    // })

    / / / / eq method
    // $("div").eq(0).click(() => {
    // console.log("eq method ")
    // })

    / / endf method
    // let res = $("div").eq(0).eq(0).eq(0).end();
    // console.log(res);

    / / CSS method
    
    // Get the style (just get the first element)
    // let res = $("div").css("background");
    // console.log(res);

    // Set the style
    // $("div").css("background","yellow");



    // // Case 3 (Set multiple styles)
    / / $(" div "). The CSS ({background: "black", width: 200, opacity: 0.3});


</script>
</html>
Copy the code

The complete code