模拟 jquery 的 $ 选择器

🌙
手机阅读
本文目录结构

模拟 jquery 的 $ 选择器

直接看代码的吧


/*********************************************
  JS 模拟 jQuery 选择器
  by http://www.cnblogs.com/zjfree
  Date 2012-02-22

  已实现:
  $('#div1') ID 选择器 (直接返回对象)
  $('.aCur') 类选择器
  $('div') 元素选择器
  $('#div1 li') 组合选择器
  $('input[type=text]:checked') 属性值选择器
  $('a', myDiv) 选择 myDiv 下的所有 a 元素
/*********************************************/

//q 查询表达式 o 父对象
function $(q, o){
    //debugger;
    // 查询表达式必须为字符串,并且不能为空。
    if(typeof(q)!=='string' || q == '') return [];

    // 使用空格分割,只处理第一个表达式
    var ss = q.split(' ');

    // 获取属性
    var attr = '';
    var s = ss[0].split(':')[0];
    if(s != ss[0])
        attr = ss[0].split(':')[1];

    var val = s.split('[')[0];
    if(val != s)
        val = s.split('[')[1].replace(/[",\]]/g,'');
    else
        val = '';
    s = s.split('[')[0];

    var obj = [];
    var sObj = null;
    // 当父对象不存在时,使用 document;
    o = o || document;
    switch(s.charAt(0))
    {
        case '#':
            //ID 选择器
            sObj = document.getElementById(s.substr(1));
            if(sObj)obj.push(sObj);
            break;
        case '.':
            // 类选择器
            var l = o.getElementsByTagName('*');
            var c = s.substr(1);
            for(var i=0; i<l.length; i++)
            if(l[i].className.search('\\b' + c + '\\b')!=-1)obj.push(l[i]);
            break;
        default:
            // 根据 tag 获取元素
            obj = o.getElementsByTagName(s);
            break;
    }

    if(val)
    {
        //[t=val] 筛选属性匹配
        var l = [];
        var a = val.split('=');
        for(var i=0; i<obj.length; i++)
            if(a.length == 2 && obj[i](a[0)] == a[1]) l.push(obj[i]);
        obj = l;
    }

    if(attr)
    {
        //: 筛选属性匹配
        var l = [];
        for(var i=0; i<obj.length; i++)
            if(obj[i](attr)) l.push(obj[i]);
        obj = l;
    }

    if(ss.length > 1)
    {
        // 递归处理表达式后续内容
        // 父元素为已获取的所有元素
        var l = [];
        for(var i=0; i<obj.length; i++){
            var ll = arguments.callee(q.substr(ss[0].length+1), obj[i]);
            if(ll.tagName) l.push(ll);
            else
            for(var j=0; j<ll.length; j++)l.push(ll[j]);
        }
        obj = l;
    }

    if(sObj && ss.length == 1){
        // 当为 ID 选择器时,直接返回对象。
        obj=sObj;
        if(obj)obj.length = 1;
    } else {
        // 去除数组中重复元素
        var l = [];
        for(var i=0; i<obj.length; i++)obj[i].$isAdd = false;
        for(var i=0; i<obj.length; i++){
            if(!obj[i].$isAdd){
                obj[i].$isAdd = true;
                l.push(obj[i]);
            }
        }
        obj = l;
    }

    return obj;
 }

更多面试题

如果你想了解更多的前端面试题,请点击下面进行选择,这里基本包涵了市场上的所有前端方面的面试题,让你面试更加顺利。

这些题库还在更新中,如果你有不错的面试题库欢迎分享给我,我整理后放上来;人人为我,我为人人,互帮互助,共同提高,祝大家都拿到心仪的Offer!

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了