使用原生JavaScript实现jQuery的css选择器

本文介绍如何使用原生JavaScript实现类似jQuery的选择器功能,包括解析复杂的CSS选择器表达式,支持ID、类和标签名选择。文章详细解释了处理不同选择器类型的方法,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用原生JS实现jQuery的css选择器,考虑以下几个问题:

1.jQuery用$符号传参的形式获取节点的对象:1)传参有可能是字符串;2)有可能是一个节点对象;3)有可能直接是一个函数,就是$(function(){}),这个形式。所以需要分三种情况

2.字符串又分以下几种情况:1)包含层层递进的css选择器,例如$('#a .b p'),中间会出现空格;2)只有一个字符串
3.不管是层层递进的后代选择器还是简单选择的情况,具体选择时每一个字符串可能是ID选择,类选择,或者普通选择
function Base(args){							//定义一个构造函数,参数为args
	this.elements=[];						//定义一个存放查找到的节点对象或者对象集合
	
	if(typeof args=='string'){					//判断传递的参数是那种情况,字符串或者对象节点或者函数
		
		if(args.indexOf(' ') !=-1){				//判断字符串的时候是否有空格
			var elements=args.split(' ');			//将字符串用空格分割成数组,并保存在elements变量里面
			var childElements=[];				//定义一个子数组,存放当前查找的节点,最后结果赋值给对象的elements数组
			var node=[]; 					
			for(var i=0;i<elements.length;i++){		//遍历elements数组,判断每个数组值得第一个字符
				if(node.length==0) node=document;	//每次查找的n.getElementById()中n为当前查找到的节点
				switch(elements[i].charAt(0)){			
					case '#':			
						childElements=[];	
						childElements.push(this.getId(elements[i].substring(1)));
						node=childElements;		
						break;		
					case '.':
						childElements=[];		//下一次循环时先将之前的大范围清空,准备放小范围
						for(var j=0;j<node.length;j++){
							var temps=this.getClass(elements[i].substring(1),node[j]);
							for(var k=0;k<temps.length;k++){
								childElements.push(temps[k]);
							}
						}
						node=childElements;		//将本次得到的节点作为父节点保存起来
						break;
					default:
						childElements=[];		
						for(var j=0;j<node.length;j++){
							var temps=this.getTagName(elements[i],node[j]);
							for(var k=0;k<temps.length;k++){
								childElements.push(temps[k]);
							}
						}
						node=childElements;					
				}
			}
			this.elements=childElements;	//将最后得到的小范围数组赋值给原型数组准备后续的操作
		}else{
			//find查找节点
			switch(args.charAt(0)){
				case '#':
					this.elements.push(this.getId(args.substring(1)));		//不一定得到一个,所以直接放进数组,不用放到数组里面的第一个
					break;		//直传一个参数,所以判断出时直接跳出循环
				case '.':
					this.elements=this.getClass(args.substring(1));	
					break;
				default:
					this.elements=this.getTagName(args);
			}
		}
	}else if(typeof args=='object'){		//undefiend和对象都返回object
		if(typeof args!='undefined'){
				this.elements[0]=args;
		}
	}else if(typeof args=='function'){
		this.ready(args);
	}
			
};
//工具函数,给原型对象中添加方法
Base.prototype.getId=function(id){	
	return document.getElementById(id);
}
Base.prototype.getClass=function(className,parentNode){
	var node=null;
	var temps=[];
	if(parentNode!=undefined){
		node=parentNode;
	}else{
		node=document;
	}
	
	var all=node.getElementsByTagName('*');	//通过标签*获取全部节点
	for(var i=0;i<all.length;i++){
		if((new RegExp('(\\s|^)' +className +'(\\s|$)')).test(all[i].className)){
			temps.push(all[i]);
		}
	}
	return temps;
}
Base.prototype.getTagName=function(tag,parentNode){
	var node=null;
	var temps=[];
	if(parentNode!=undefined){
		node=parentNode;
	}else{
		node=document;
	}
	var tags=node.getElementsByTagName(tag);
	for(var i=0;i<tags.length;i++){
		temps.push(tags[i]);
	}
		
	return temps;
		
}
Base.prototype.ready=function(args){
	//DOM加载
}
//通过$调用
var $=function(args){
	return new Base(args);
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值