封装选择器

平时写js,用到选择器是必不可少的,一直用框架的选择器,内部到底是怎么样的呢

(function(){
var doc = document,
REG_ID = /^#[\w-]+$/,
REG_QUERY = /^(:?#([\w-]+))?\s*([\w-]+|\*)?\.?([\w-]+)?$/;

//将封装好的默认函数在进行集中处理,用正则来区分传入的selector
function query(selector,content){
var match, ret = [], id, tag, cls ,t;
content = tuneContent(content);

if(isString(selector)){
selector = trim(selector);

//如果传入的是id,那么就直接用封装好的getElementById
if(REG_ID.test(selector)){
t = getElementById(selector.slice(1),content);
if(t) ret = [t];//返回数组
//exec返回第一个匹配的字符串,和所有分组的反向引用(即正则中括号包裹的部分)
}else if((match = REG_QUERY.exec(selector))){
id = match[1];
tag = match[2];
cls = match[3];

//如果获取到的反向引用中有id,那么将content设为根据id获取到的元素,
//否则仍旧为tuneContent调整后的值
if(content = id ? getElementById(id,content) : content){
//如果有class
if(cls){
//如果没有id并且传入的selector参数中有空格,即排除#id.cls
if(!id && selector.indexOf(" ") !== -1){
//那么使用封装好的getElementsByClassName来获取元素
ret = getElementsByClassName(cls,tag,content);
}else{
//处理#id.cls 这个selector参数应该表示的是#id并且这个id的className值为cls
//那么先根据id取到元素,在判断取到的这个元素的className是否含有cls
t = getElementById(id,content);
if(t && hacClass(t,cls)){
ret = [t];
}
}

}else if(tag){//如果有tag
//那么直接用原生的getElementsByTagName来获取元素
ret = content.getElementsByTagName(tag);
}
}
}
}
return ret;
}

function get(){
return query(selector,content)[0];
}

//将content调整到一个合理的值
function tuneContent(content){
//如果content未定义,那么content=doc
if(content === undefined){
content = doc;
//如果content是个id,那么content=根据id获取到元素
}else if(isString(content) && REG_ID.test(content)){
content = getElementById(content.slice(1),doc);
//如果content即不是元素或者不是doc文档类型,那么content=null
}else if(content && content.nodeType !== 1 && content.nodeType !==9){
content = null;
}

return content;

}

//封装默认的getElementById函数
function getElementById(el,content){
if(content.nodeType !== 9){
content = content.ownerDocument;
}
return content.getElementById(el);
}

//封装默认的getElementsByClassName函数(高级浏览器才有这个默认函数)
function getElementsByClassName(cls,tag,content){
if(!cls) return;
var els = content.getElementsByClassName(cls),
ret = els,j=0;

//根据传入的tag筛选获取到的元素
if(tag && tag != "*"){
ret = [];
for(var i = 0,len = els.length;i<len;i++){
el = els[i];
if(el.tagName == tag.toUpperCase()){
ret[j++] = el;
}
}
}
return ret;
}

//如果不支持getElementsByClassName,则降级使用querySelectorAll,
//再不支持,则先根据tag获取到元素,在遍历这些元素,看这些元素的className是否含有传入的className值
if(!doc.getElementsByClassName){
if(doc.querySelectorAll){
getElementsByClassName = function(cls,tag,content){
return content.querySelectorAll((tag ? tag : "") +"." + cls);
}
}else{
getElementsByClassName = function(cls,tag,content){
var els = content.getElementsByTagName(tag),
ret = [],j=0,cls = " "+cls+" ";
for(var i = 0,len = els.length;i<len;i++){
var el = els[i],t = el.className;
if(t && hasClass(el,cls)){
ret[j++] = el;
}
}
return ret;
}
}
}


function isString(str){
return str && typeof str === "string";
}

function trim(str){
return str.replace(/(^\s*)|(\s*$)/g,"");
}

//不支持多个cls同时判断
function hasClass(el,cls){
var cls = " " + cls + " ",
elcls = " " + el.className + " ";
return elcls.indexOf(cls) > -1;
}

})();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值