Js封装库——css选择器
在css中我们可以很简单地使用css选择器来对节点对象进行选择,并对其进行style设置。现在,我们想通过js对html的css样式进行动态设置,想以css的形式进行设置,例如我们想通过$(‘#box p’)来选中id为’box’的节点对象的子节点中的p节点,我们应该怎么来实现呢?
1.首先,创建几个文件:index.html、index.js、base.js
其中,index.html如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>博客前端:下拉菜单</title>
<script src="index.js"></script>
<script src="base.js"></script>
</head>
<body>
<div id="box">
<p>yaodebian</p>
<p id="yao">yaodebian</p>
<p class="yao">yaodebian</p>
</div>
</body>
</html>
2.接下来,我们往封装库文件base.js中编写我们所需要的css选择器:
首先,我们需要创建一个对象用来封装相应功能的代码:
function Base(selector) {};//其中的selector为咱们定义的选择文本,如‘#box p’
另外,我们定义一个函数来简化执行css选择器功能:
//封装对象初始化
var $ = function (selector) {
return new Base(selector);
}
以后我们进行节点动态选择时即用$(‘#box p’)即可;
然后我们往Base方法中添加内容:
function Base(selector) {
//创建一个数组,来保存获取的节点和节点数组
this.elements = [];
//如果selector为一个节点对象,偏将selector直接存放与Base对象中的elements数组中
if(typeof selector=='object'){
this.elements.push(selector);
alert(1);
}
else if(typeof selector=='string'){//若selector是一个字符串,即我们的css选择文本
var elements=selector.split(' ');//将层次分开,如’#box p’分成两个层次#box和p
var parentNode=[];//用来保存上一层次的节点数组
var target=[];//目标节点数组(即我们要选定的节点对象列表)
parentNode.push(document);//初始状态下parentNode为document对象
for(var i=0;i<elements.length;i++){//层次遍历
switch(elements[i].charAt(0)){//判断选择前缀(‘#’、’.’或’’(没有前缀,即标签名))
case '#'://id选择器
target=[];
if(this.getId(elements[i].substring(1))){//直接获取该节点对象并存于target中,其中的elements[i].substring(1)即将前缀去掉
target.push(this.getId(elements[i].substring(1)));
}
parentNode=target;//为下一层保存上层节点列表(如果有下一层的话)
break;
case '.'://class选择器
target=[];
//对于上一层的每一个节点对象,我们都得从中查询遍历此层节点
for(var j=0;j<parentNode.length;j++){
var temp=this.getClass(elements[i].substring(1),parentNode[j]);
for(var a=0;a<temp.length;a++){
target.push(temp[a]);
}
}
parentNode=target;
break;
default://元素选择器
target=[];
for(var j=0;j<parentNode.length;j++){
var temp=this.getTagName(elements[i],parentNode[j]);
for(var a=0;a<temp.length;a++){
target.push(temp[a]);
}
}
parentNode=target;
}
}
this.elements=target;
}
}
//获取ID节点
Base.prototype.getId = function (id) {
return document.getElementById(id);
};
//注:getElementById是document独有的方法,即我们不可以用任意一元素节点对象调用该方法
//获取元素节点
Base.prototype.getTagName = function (tag,parentNode) {
var tags =parentNode.getElementsByTagName(tag);//注:tags是一个数组
var target=tags;
// for (var i = 0; i < tags.length; i ++) {
// target.push(tags[i]);
// }
return target;
};
//获取特定class值的元素节点
Base.prototype.getClass=function(className,parentNode){
var all=parentNode.getElementsByTagName('*');//获取parentNode下的所有元素子节点
var target=[];
for(var i=0;i<all.length;i++){
if(all[i].className==className){
target.push(all[i]);
}
}
return target;
}
//设置元素样式,同时获取某元素的某属性的值
Base.prototype.css = function (attr, value) {
for (var i = 0; i < this.elements.length; i ++) {
if(arguments.length==1){
return getStyle(this.elements[i],attr);
}
this.elements[i].style[attr] = value;
}
return this;//为了实现连缀而返回this
}
3.在index.js中我们使用css选择器:
window.οnlοad=function(){
$('#box #yao').css('color','red');
}
执行以上程序,html文件中<p id="yao">yaodebian</p>节点被选中,里面的内容变为红色