Simple implementation of jQuery tool method $.Callbacks()

Simple implementation of the jQuery tool method $.Callbacks():

(function () {
    //Create a jQuery Constructor
    function jQuery(selector) {
        return new jQuery.prototype.init(selector);
    }
    //by jQuery Prototype addition init Property that all instances can use
    jQuery.prototype.init = function (selector) {
        this.length = 0; //by this Add to length Attribute with a value of 0
        //elect dom And packed as jQuery Object Return
        //judge selector yes null and undefined and dom Object and id and class Situation
        if (selector == null) { //judge selector yes null or undefined
            return this;
        } else if (typeof selector === 'string' && selector.indexOf('.') != -1) { //selector yes class Situation
            var dom = document.getElementsByClassName(selector.slice(1));
        } else if (typeof selector === 'string' && selector.indexOf("#") != -1) { //selector yes id Situation
            var dom = document.getElementById(selector.slice(1));
        }

        if (selector instanceof Element || dom.length == undefined) { //(selector yes dom object) || (selector yes id,An object was returned, but the object did not length attribute)
            this[0] = dom || selector; //(selector yes id) || (selector yes dom object)
            this.length++;
        } else { //selector yes class,Returned is an array of classes
            for (var i = 0; i < dom.length; i++) {
                this[i] = dom[i];
                this.length++;
            }
        }
    };

    //by jQuery Prototype addition css Property that all instances can use
    jQuery.prototype.css = function (config) {
        for (var i = 0; i < this.length; i++) {
            for (var prop in config) {
                this[i].style[prop] = config[prop];
            }
        }

        return this; //The essence of chain call
    };

    //by jQuery Object's prevObject Attribute assignment so that you can use end()Method
    jQuery.prototype.pushStack = function (dom) {
        //dom yes jQuery object
        if (dom.constructor != jQuery) { //dom Is Native dom object
            dom = jQuery(dom); //Will be native dom Objects wrapped in jQuery object
        }
        dom.prevObject = this; //take

        return dom;
    };

    //by jQuery Prototype addition get Property that all instances can use
    jQuery.prototype.get = function (num) {
        //num == null Return Array
        //num >= 0 Return this[num]
        //num < 0 Return this[length + num]
        return (num != null) ? ((num >= 0) ? (this[num]) : (this[num + this.length])) : ([].slice(this, 0));
    };

    //by jQuery Prototype addition get Property that all instances can use
    jQuery.prototype.eq = function (num) {
        return this.pushStack(this.get(num)); //call jQuery.prototype.get()Function get to dom Object, encapsulated as jQuery Object and is jQuery Object Addition prevObject attribute
    };

    //by jQuery Prototype addition add Property that all instances can use
    jQuery.prototype.add = function (selector) {
        var curObj = jQuery(selector); //Currently Passed add Added selector Selected jQuery object
        var prevObj = this; //call add()Of jQuery object
        var newObj = jQuery();

        for (var i = 0; i < curObj.length; i++) {
            newObj[newObj.length++] = curObj[i];
        }

        for (var i = 0; i < prevObj.length; i++) {
            newObj[newObj.length++] = prevObj[i];
        }

        this.pushStack(newObj); //by jQuery Object Addition prevObject attribute

        return newObj; //Will be merged jQuery Object Return
    };

    //by jQuery Prototype addition end Property that all instances can use
    jQuery.prototype.end = function () {
        return this.prevObject; //Return directly to the previous one jQuery object
    };

    //by jQuery Prototype addition on Property that all instances can use
    jQuery.prototype.on = function (type, handle) {
        for (var i = 0; i < this.length; i++) {
            if (!this[i].cacheEvent) {//Judging Every Native dom Is there an event in the object
                this[i].cacheEvent = {}; //For every native dom Object Add Binding Event
            }
            if (!this[i].cacheEvent[type]) {//Determine whether each native object has type Binding events for types
                this[i].cacheEvent[type] = [handle];//No handler array was added for this type of event
            } else {
                this[i].cacheEvent[type].push(handle);//If this type of event already exists, place it directly in the array
            }
        }
    };

    //by jQuery Prototype addition trigger Property that all instances can use
    jQuery.prototype.trigger = function (type) {
        var self = this;//Will call trigger Functional jQuery Objects stored in self in
        var params = arguments.length > 1 ? [].slice.call(arguments, 1) : [];//Judgement Call trigger()Is function passed in except type Other parameters
        for (var i = 0; i < this.length; i++) {//Loop traversal this
            if (this[i].cacheEvent[type]) {//Judge every native dom Is there any storage in the object type Events of type
                this[i].cacheEvent[type].forEach(function (ele, index) {//When there are multiple events of the same type, execute them all in turn
                    ele.apply(self, params);//adopt self Call the event and pass in the parameters
                });
            }
        }
    };

    //by jQuery Prototype addition queue Property that all instances can use
    jQuery.prototype.queue = function (type, handle) {
        var queueObj = this;//jQuery object
        var queueName = arguments[0] || 'fx';//The first parameter, which is the queue name
        var addFunc = arguments[1] || null;//The second parameter is the processing function
        var len = arguments.length;//Get the number of parameters

        //If only one parameter is passed type,Return directly to the queue array
        if(len == 1){
            return queueObj[0][queueName];
        }

        //take out jQuery In dom Object, for dom Object Add Queue Events
        queueObj[0][queueName] == undefined ? (queueObj[0][queueName] = [addFunc]) : (queueObj[0][queueName].push(addFunc));
        
        return this;
    };

    //by jQuery Prototype addition dequeue Property that all instances can use
    jQuery.prototype.dequeue = function (type) {
        var self = this;
        var queueName = arguments[0] || 'fx';
        var queueArr = this.queue(queueName);

        var currFunc = queueArr.shift();
        if(currFunc == undefined){
            return ;
        }

        var next = function(){
            self.dequeue(queueName);
        }

        currFunc(next);
        return this;
    };

    //by jQuery Add to Callbacks Properties, jQuery You can use this property
    jQuery.Callbacks = function () {
        // 'once' 'memory' 'once memory' null
        
        var options = arguments[0] || '';// Storage parameters
        //storage add Method to join
        var list = [];

        var fireIndex = 0;//Records the index of the current function to be executed

        var fired = false;//Is the recording method being used by fire too

        var args = [];//List of actual parameters

        var fire = function(){
            for(; fireIndex < list.length; fireIndex++){
                list[fireIndex].apply(window, args)
            }
            if(options.indexOf('once') != -1){
                list = [];
                fireIndex = 0;
            }
        }

        return {
            add: function(func){
                list.push(func);
                if(options.indexOf('memory') != -1 && fired){//The parameter is'memory' && Executed fired
                    fire();//Following execution add Functions of
                }
                return this;
            },
            fire: function(){
                fireIndex = 0;
                fired = true;//
                args = arguments;
                fire();
            }
        }
    };

    //Above jQuery The constructor is new One jQuery.prototype.init Object,
    //jQuery.prototype.init Not on object jQuery.prototype On css()Method
    //So add the following sentence to let jQuery.prototype.init Object can be called jQuery.prototype On css()Method
    jQuery.prototype.init.prototype = jQuery.prototype;

    //Let the outside pass through $()perhaps jQuery()call
    window.$ = window.jQuery = jQuery;
}());
myJquery.js

Call the $.Callbacks() method:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./myJquery.js"></script>
    <script>
        var cb = $.Callbacks();
        function a(){
            console.log("a null");
        }
        function b(){
            console.log("b null");
        }
        cb.add(a);
        cb.add(b);
        cb.fire();
        cb.fire();


        var cb = $.Callbacks('once');
        function c(){
            console.log("c once");
        }
        function d(){
            console.log("d once");
        }
        cb.add(c);
        cb.add(d);
        cb.fire();
        cb.fire();


        var cb = $.Callbacks('memory');
        function e(){
            console.log("e memory");
        }
        
        cb.add(e);
        cb.fire();
        function f(){
            console.log("f memory");
        }
        cb.add(f);
        cb.fire();
    </script>
</body>
</html>
index.html

Effect display:

 

 

(function () {
//Create a jQuery constructor
    function jQuery(selector) {
        return new jQuery.prototype.init(selector);
    }
//Add init attribute to the prototype of jQuery, which can be used by all instances
    jQuery.prototype.init = function (selector) {
this.length = 0; //Add a length attribute to this and assign a value of 0
//Select dom and wrap it as a jQuery object to return
//Judge if selector is null and undefined and dom object and id and class
if (selector == null) {//Judge that the selector is null or undefined
            return this;
} else if (typeof selector =='string'& & selector.indexOf('.)!= -1) {//selector is a case of class
            var dom = document.getElementsByClassName(selector.slice(1));
} else if (typeof selector =='string'& & selector.indexOf('#')!= -1) {//selector is the case of id
            var dom = document.getElementById(selector.slice(1));
        }

if (selector instance of Element || dom.length == undefined) {// (selector is a DOM object) | | (selector is id, returns an object, object has no length attribute)
this[0] = dom | | selector; //(selector is id) | | (selector is a dom object)
            this.length++;
} else {//selector is a class and returns an array of classes
            for (var i = 0; i < dom.length; i++) {
                this[i] = dom[i];
                this.length++;
            }
        }
    };

//Add a css attribute to the jQuery prototype, which can be used by all instances
    jQuery.prototype.css = function (config) {
        for (var i = 0; i < this.length; i++) {
            for (var prop in config) {
                this[i].style[prop] = config[prop];
            }
        }

return this; //essence of chain call
    };

//assign a value to the prevObject property of the jQuery object so that the end() method can be used
    jQuery.prototype.pushStack = function (dom) {
//dom is a jQuery object
if (dom.constructor!= jQuery) {//dom is a native DOM object
DOM = jQuery(dom); //Wrap native DOM objects into jQuery objects
        }
dom.prevObject = this; //will

        return dom;
    };

//Add a get property for the jQuery prototype, which can be used by all instances
    jQuery.prototype.get = function (num) {
* Return array //num == null
* Return this[num] //num >= 0
} //num < 0 returns this[length + num]
        return (num != null) ? ((num >= 0) ? (this[num]) : (this[num + this.length])) : ([].slice(this, 0));
    };

//Add a get property for the jQuery prototype, which can be used by all instances
    jQuery.prototype.eq = function (num) {
return this.pushStack(this.get(num)); //Call the jQuery.prototype.get() function to get the dom object, encapsulate it as a jQuery object, and add the prevObject attribute to the jQuery object
    };

//Add an add attribute to the jQuery prototype, which can be used by all instances
    jQuery.prototype.add = function (selector) {
var curObj = jQuery(selector); //the jQuery object currently selected by the add-added selector
var prevObj = this; //Call jQuery object of add()
        var newObj = jQuery();

        for (var i = 0; i < curObj.length; i++) {
            newObj[newObj.length++] = curObj[i];
        }

        for (var i = 0; i < prevObj.length; i++) {
            newObj[newObj.length++] = prevObj[i];
        }

this.pushStack(newObj); //Add a prevObject attribute to a jQuery object

return newObj; //return the merged jQuery object
    };

//Add an end attribute for the jQuery prototype, which can be used by all instances
    jQuery.prototype.end = function () {
return this.prevObject; //return directly to the previous jQuery object
    };

//Add on attribute to the prototype of jQuery, which can be used by all instances
    jQuery.prototype.on = function (type, handle) {
        for (var i = 0; i < this.length; i++) {
If (! this[i].cacheEvent) {//Determine if there are events in each native dom object
this[i].cacheEvent = {}; //Add binding events for each native dom object
            }
If (! this[i].cacheEvent[type]) {//Determine if each native object has a binding event of type
this[i].cacheEvent[type] = [handle]; //No handler array added for this type of event
            } else {
this[i].cacheEvent[type].push(handle); //If there is already an event of this type, put it directly into the array
            }
        }
    };

//Add a trigger attribute to the jQuery prototype, which can be used by all instances
    jQuery.prototype.trigger = function (type) {
var self = this; //Store the jQuery object that calls the trigger function in the self
var params = arguments.len gt h > 1? [].slice.call(arguments, 1): []; //Determine if a trigger() function is called with parameters other than type
for (var I = 0; I < this.length; i+) {//loop traverses this
if (this[i].cacheEvent[type]) {//Determine whether a type-type event is stored in each native dom object
this[i].cacheEvent[type].forEach(function (ele, index) {// When there are multiple events of the same type, execute them all in turn
ele.apply(self, params); //invoke events through self and pass in parameters
                });
            }
        }
    };

//Add a queue property to the prototype of jQuery that all instances can use
    jQuery.prototype.queue = function (type, handle) {
var queueObj = this;//jQuery object
var queueName = arguments[0] ||'fx'; //first parameter, queue name
var addFunc = arguments[1] || null; //The second parameter is the processing function
var len = arguments.length; //Get the number of parameters

//Return directly to the queue array if only one parameter type is passed
        if(len == 1){
            return queueObj[0][queueName];
        }

//Remove the dom object in jQuery to add queue events to the dom object
        queueObj[0][queueName] == undefined ? (queueObj[0][queueName] = [addFunc]) : (queueObj[0][queueName].push(addFunc));
        
        return this;
    };

//Add a dequeue attribute to the prototype of jQuery that all instances can use
    jQuery.prototype.dequeue = function (type) {
        var self = this;
        var queueName = arguments[0] || 'fx';
        var queueArr = this.queue(queueName);

        var currFunc = queueArr.shift();
        if(currFunc == undefined){
            return ;
        }

        var next = function(){
            self.dequeue(queueName);
        }

        currFunc(next);
        return this;
    };

//Add Callbacks property to jQuery, which jQuery can use
    jQuery.Callbacks = function () {
        // 'once' 'memory' 'once memory' null
        
var options = arguments[0] |';// storage parameters
Method of //Store add to join
        var list = [];

var fireIndex = 0; //Record the index of the current function to be executed

var fired = false; //Recording method fired

var args = []; //list of actual parameters

        var fire = function(){
            for(; fireIndex < list.length; fireIndex++){
                list[fireIndex].apply(window, args)
            }
            if(options.indexOf('once') != -1){
                list = [];
                fireIndex = 0;
            }
        }

        return {
            add: function(func){
                list.push(func);
if(options.indexOf('memory')!=-1 && fired) {// parameter is'memory'&& fired has been executed
fire(); //Then execute the function that follows add
                }
                return this;
            },
            fire: function(){
                fireIndex = 0;
                fired = true;//
                args = arguments;
                fire();
            }
        }
    };

//The jQuery constructor above is a new jQuery.prototype.init object,
There is no css() method on jQuery.prototype on the //jQuery.prototype.init object
//So add the following sentence so that the jQuery.prototype.init object can call the css() method on jQuery.prototype
    jQuery.prototype.init.prototype = jQuery.prototype;

//Make external calls through $() or jQuery()
    window.$ = window.jQuery = jQuery;
}());

Tags: Javascript JQuery Attribute

Posted on Fri, 15 May 2020 10:10:10 -0700 by zerogreen