Understanding Implementation Principles from jQuery - Part 1

Keywords: JQuery

We mainly understand some common methods in jQuery, including click (), show (), hide (), hover (), css (), etc.

attr(),toggle(),eq(),find(),index();

Step 1: Get the elements on the page
function VQuery(vArg)   //Parameters can make fn, oArg (object), sArg (string), so setting vArg can be any of three parameters
{
	//Elements are used to save selected elements
	this.elements=[];
	switch( typeof vArg)
	{
		case 'function': 
			myAddEvent(window, 'load', vArg);
			break;
		case 'string':
			switch(vArg.charAt(0))
			{
				case '#':  //ID
					var obj=document.getElementById(vArg.substring(1));
					
					this.elements.push(obj);
			    	break;
				case '.': //class
					this.elements=getByClass(document, vArg.substring(1));
					break;
				default: //tagName
					this.elements=document.getElementsByTagName(vArg);
			}
			break;
		case 'object':
			this.elements.push(vArg);
	}
}

Note: The type of parameter is not accurate, so it is expressed by vArg.

2. Selecting elements by class

function getByClass(oParent, sClass)
{
	var aEle = oParent.getElementsByTagName('*');
	var aResult=[];
	
	for(var i=0; i<aEle.length; i++)
	{
		if(aEle[i].className == sClass)
		{
			aResult.push(aEle[i]);
		}
	}
	
	return aResult;
}

3. Replace new VQuery with $to facilitate code writing

function $(vArg)
{
	return new VQuery(vArg);
	}

4. Bind events before writing events

function myAddEvent(obj, sEv, fn){
	
	if(obj.attachEvent)
	{	
		obj.attachEvent('on'+sEv, function(){
			
			fn.call(obj);
			});  //Solve this problem in binding events by call
	}
	else
	{
		obj.addEventListener(sEv, fn, false);
	}
}
Note: this will point to window in the binding event, so call () is used as the solution.

Note: There are four situations in which this cannot be used: 1. Interline; 2. Nesting; 3. Timer; 4. Event binding;

5. click events

VQuery.prototype.click=function(fn){
	var i=0;
	
	for(i=0; i<this.elements.length;i++){
		
		myAddEvent(this.elements[i], 'click', fn);
		}
	};

6. show display

VQuery.prototype.show=function()
{
	for(var i=0; i<this.elements.length; i++)
	{
		this.elements[i].style.display='block';
		}
};

7. hide hiding

VQuery.prototype.hide=function()
{
	for(var i=0; i<this.elements.length; i++)
	{
		this.elements[i].style.display='none';
		}
};

8,hover(mouseover,mouseout)

VQuery.prototype.hover=function(fnOver, fnOut)
{
    for(var i=0; i<this.elements.length; i++){
        
        myAddEvent(this.elements[i], 'mouseover', fnOver);
        myAddEvent(this.elements[i], 'mouseout', fnOut);
        }
};

9. The method of obtaining css

VQuery.prototype.css=function(attr, value){
	
	if(arguments.length==2)   //Set style
	{
		var i=0;
		for(i=0; i<this.elements.length; i++){
			this.elements[i].style[attr]=value;
			}
		}
	else{  //Get style
		
		return getStyle(this.elements[0], attr);
		}
	};
Note: It's okay to use style when setting up, but when getting elements, style only gets style between lines.

So the solution is:

function getStyle(obj, attr){
	
	if(obj.currentStyle)
	{
		return obj.currentStyle[attr];
		}
		
	else{
		return getComputedStyle(obj, false)[attr];
		}
	}

10. attr method, similar to css settings, just does not get css style, but gets attributes in html

VQuery.prototype.attr=function(attr, value){
	
	if(arguments.length==2){
		var i=0;
		for(i=0; i<this.elements.length; i++){
			
			this.elements[i][attr]=value;
			}
		}
	else{
		
		return this.elements[0][attr];
		}
};

11. toggle switching events can have multiple parameters. The first point is the first one, which appears in turn, and then repeats.

VQuery.prototype.toggle=function(){
	
	var i=0;
	var _arguments=arguments;
	for(i=0; i<this.elements.length; i++){
		
		addToggle(this.elements[i]);
		}
	
	function addToggle(obj){
		
		var count=0;
		myAddEvent(obj, 'click', function(){
			_arguments[count%_arguments.length].call(obj);
			count++;
			});
		}
	
};

12. eq method: subscripts similar to arrays

VQuery.prototype.eq=function(n){
	
	return $(this.elements[n]);	
};

13. Find method is used to find sub-elements

VQuery.prototype.find=function(str){ //In default 2, one is the label name and the other is class, regardless of the id suboption under id.
	
	var i=0;
	var aResult=[];
	for(i=0; i<this.elements.length; i++){
		
		switch(str.charAt(0))
		{
			case '.':  //class
				var aEle=getByClass(this.elements[i], str.substring(1));
				aResult=aResult.concat(aEle);
				break;
			
			default:   //Label
				var aEle=this.elements[i].getElementsByTagName(str);
				//aResult=aResult.concat(aEle);
				appendArr(aResult, aEle);
		}
	}
	var newVquery=$();
	
	newVquery.elements=aResult;
	
	return newVquery;
};

function getIndex(obj){
	
	var aBrother=obj.parentNode.children;
	var i=0;
	for(i=0; i<aBrother.length; i++){
		
		if(aBrother[i]==obj){
			
			return i;
			}
		}
	}

Note: The concat mentioned above can't be used. aLi is an array-like structure, but it's not an array, so

You can't use concat to push elements in aLi into an array.

function appendArr(arr1, arr2)
{
	var i=0;
	
	for(i=0;i<arr2.length;i++)
	{
		arr1.push(arr2[i]);
	}
}

14. The index method is actually the index of the element (the element is numbered in the parent level)

VQuery.prototype.index=function(){
	
	return getIndex(this.elements[0]);
	};




Posted by gtzpower on Sun, 26 May 2019 11:01:55 -0700