实现一个类似jquery选择器的小轮子(二)

  大致的思路已经整理出来,

  上一次遍历到的子级是下一次遍历到的父级;

首先开始是对$(str)里面的str字符串进行切片;

var str = ‘  div .abc .edf   ‘
$(str);
//切片思路如下
//首先在使用选择器时可能手误,前面空了空格,或者后面空了空格;为了增加容错性,在此先对字符串使用trim方法.
str = str.replace(/^\s+|\s+$/g,‘‘);
console.log(str);//得到‘div .abc .edf‘;
//开始对字符串进行切割
var aStr = str.replace(/\s+/g,‘ ‘);
console.log(aStr );//得到 ‘div‘,‘.abc‘,‘.edf‘的数组

接着实现获取元素的函数;

思路是让上级遍历的子级变成下次遍历的父级

//获取元素
function getEle(str){
    // 切
    var arr = str.replace(/^\s+|\s+$/g,"").replace(/\s+/g," ").split(" ");
    var aParent = [document];
    var aChild  = [];

    //循环获取元素
    for(var i = 0; i < arr.length; i++){

        aChild = getByStr(aParent,arr[i]);//先预定义一个利用字符获取元素的方法

        //核心: 上一次子级 是下一次父级
        aParent = aChild;
    }

    return aChild;
}

定义字符获取元素方法;

function getByClass(oParent,sClass){

    if(oParent.getElementsByClassName){
        return oParent.getElementsByClassName(sClass);
    }

    var result = [];
    var re = new RegExp("\\b"+sClass+"\\b");

    var aEle = oParent.getElementsByTagName("*");

    for(var i = 0; i < aEle.length; i++){
        if( re.test(aEle[i].className) ){
            result.push(aEle[i]);
        }
    }
    return result;
}
function getByStr(aParent,str){
    var aChild = [];

    //选择元素
    //str  #id  .class  tagname
    for(var i = 0; i < aParent.length; i++){
        switch(str.charAt(0)){
            case "#":// id
                var obj = document.getElementById(str.substring(1));
                aChild.push(obj);
                break;
            case ".":// 类
                var aEle = getByClass(aParent[i],str.substring(1));
                //aChild = aChild.concat(aEle);
                for(var j = 0; j < aEle.length; j++){
                    aChild.push(aEle[j]);
                }
                break;
            default://标签

                //tagname#id
                if(/^[a-z0-9]+#[a-z0-9\-_$]+$/i.test(str)){
                    //[tagname,id]
                    var arr = str.split("#");
                    var aEle = aParent[i].getElementsByTagName(arr[0]);
                    for(var j = 0; j < aEle.length; j++){
                        if(aEle[j].id == arr[1]){
                            aChild.push(aEle[j]);
                        }
                    }
                //li.box
                } else if(/[a-z0-9]+\.[a-z0-9\-_$]+$/i.test(str)){
                     // [tagname,class]
                     var arr = str.split(".");
                     var aEle = aParent[i].getElementsByTagName(arr[0]);
                    for(var j = 0; j < aEle.length; j++){
                        if(aEle[j].className == arr[1]){
                            aChild.push(aEle[j]);
                        }
                    }
                //input[type=button]
                } else if(/\w+\[\w+=\w+\]/.test(str)){

                    //arr [input,type,button,]
                    var arr = str.split(/\[|=|\]/);
                    var aEle = aParent[i].getElementsByTagName(arr[0]);
                    for(var j = 0; j < aEle.length; j++){

                        if(aEle[j].getAttribute(arr[1])  == arr[2]){
                            aChild.push(aEle[j]);
                        }
                    }
                    //li:first  li:eq(index)
                } else if(/\w+:\w+(\(\.\))?/.test(str)){

                    /*[li,eq,index,]
                      arr[0]  tagname
                      arr[1]  first/eq/gt/lt/odd/even
                      arr[2]  内容
                    */
                    var arr = str.split(/:|\(|\)/);
                    var aEle = aParent[i].getElementsByTagName(arr[0]);
                    switch(arr[1]){
                        case "first":
                            aChild.push(aEle[0]);
                            break;
                        case "last":
                           aChild.push(aEle[aEle.length - 1]);
                            break;
                        case "eq":
                            aChild.push(aEle[arr[2]]);
                            break;
                        case "gt"://大于
                            for(var j = parseInt(arr[2]) + 1; j < aEle.length; j++){
                                aChild.push(aEle[j]);

                            }

                        break;
                        case "lt"://小于
                            for(var j = 0; j < parseInt(arr[2]); j++){
                                aChild.push(aEle[j]);

                            }
                            break;
                        case "odd":
                            for(var j = 0; j < aEle.length; j++){
                                if(j%2 == 1){
                                    aChild.push(aEle[j]);
                                }
                            }
                        break;
                        case "even":
                            for(var j = 0; j < aEle.length; j+=2){
                                aChild.push(aEle[j]);
                            }
                        break;
                    }

                }else {//纯标签
                    var aEle = aParent[i].getElementsByTagName(str);
                    //aChild = aChild.concat(aEle);
                    for(var j = 0; j < aEle.length; j++){
                        aChild.push(aEle[j]);
                    }
                }
        }

    }
    return aChild;
}

以上的字符获取元素方法算是比较简单的了。较难的还是一开始的思路定稿。

在此这个选择器也基本完成了,其实直接用sizzle选择器的话会更强大更轻便,但本着生命便是折腾,前端重复造轮子的态度,还是折腾了以上的方法。

全部代码如下

function getByClass(oParent,sClass){

    if(oParent.getElementsByClassName){
        return oParent.getElementsByClassName(sClass);
    }

    var result = [];
    var re = new RegExp("\\b"+sClass+"\\b");

    var aEle = oParent.getElementsByTagName("*");

    for(var i = 0; i < aEle.length; i++){
        if( re.test(aEle[i].className) ){
            result.push(aEle[i]);
        }
    }
    return result;
}

function getByStr(aParent,str){
    var aChild = [];

    //选择元素
    //str  #id  .class  tagname
    for(var i = 0; i < aParent.length; i++){
        switch(str.charAt(0)){
            case "#":// id
                var obj = document.getElementById(str.substring(1));
                aChild.push(obj);
                break;
            case ".":// 类
                var aEle = getByClass(aParent[i],str.substring(1));
                //aChild = aChild.concat(aEle);
                for(var j = 0; j < aEle.length; j++){
                    aChild.push(aEle[j]);
                }
                break;
            default://标签

                //tagname#id
                if(/^[a-z0-9]+#[a-z0-9\-_$]+$/i.test(str)){
                    //[tagname,id]
                    var arr = str.split("#");
                    var aEle = aParent[i].getElementsByTagName(arr[0]);
                    for(var j = 0; j < aEle.length; j++){
                        if(aEle[j].id == arr[1]){
                            aChild.push(aEle[j]);
                        }
                    }
                //li.box
                } else if(/[a-z0-9]+\.[a-z0-9\-_$]+$/i.test(str)){
                     // [tagname,class]
                     var arr = str.split(".");
                     var aEle = aParent[i].getElementsByTagName(arr[0]);
                    for(var j = 0; j < aEle.length; j++){
                        if(aEle[j].className == arr[1]){
                            aChild.push(aEle[j]);
                        }
                    }
                //input[type=button]
                } else if(/\w+\[\w+=\w+\]/.test(str)){

                    //arr [input,type,button,]
                    var arr = str.split(/\[|=|\]/);
                    var aEle = aParent[i].getElementsByTagName(arr[0]);
                    for(var j = 0; j < aEle.length; j++){

                        if(aEle[j].getAttribute(arr[1])  == arr[2]){
                            aChild.push(aEle[j]);
                        }
                    }
                    //li:first  li:eq(index)
                } else if(/\w+:\w+(\(\.\))?/.test(str)){

                    /*[li,eq,index,]
                      arr[0]  tagname
                      arr[1]  first/eq/gt/lt/odd/even
                      arr[2]  内容
                    */
                    var arr = str.split(/:|\(|\)/);
                    var aEle = aParent[i].getElementsByTagName(arr[0]);
                    switch(arr[1]){
                        case "first":
                            aChild.push(aEle[0]);
                            break;
                        case "last":
                           aChild.push(aEle[aEle.length - 1]);
                            break;
                        case "eq":
                            aChild.push(aEle[arr[2]]);
                            break;
                        case "gt"://大于
                            for(var j = parseInt(arr[2]) + 1; j < aEle.length; j++){
                                aChild.push(aEle[j]);

                            }

                        break;
                        case "lt"://小于
                            for(var j = 0; j < parseInt(arr[2]); j++){
                                aChild.push(aEle[j]);

                            }
                            break;
                        case "odd":
                            for(var j = 0; j < aEle.length; j++){
                                if(j%2 == 1){
                                    aChild.push(aEle[j]);
                                }
                            }
                        break;
                        case "even":
                            for(var j = 0; j < aEle.length; j+=2){
                                aChild.push(aEle[j]);
                            }
                        break;
                    }

                }else {//纯标签
                    var aEle = aParent[i].getElementsByTagName(str);
                    //aChild = aChild.concat(aEle);
                    for(var j = 0; j < aEle.length; j++){
                        aChild.push(aEle[j]);
                    }
                }
        }

    }
    return aChild;
}

//获取元素
function getEle(str){
    // 切
    var arr = str.replace(/^\s+|\s+$/g,"").replace(/\s+/g," ").split(" ");
    var aParent = [document];
    var aChild  = [];

    //循环获取元素
    for(var i = 0; i < arr.length; i++){

        aChild = getByStr(aParent,arr[i]);

        //核心: 上一次子级 是下一次父级
        aParent = aChild;
    }

    return aChild;
}

时间: 2024-10-06 16:36:41

实现一个类似jquery选择器的小轮子(二)的相关文章

实现一个类似jquery选择器的小轮子(一)

 最近在做移动端的项目,主管说不用jq,尽量用轻量级的类库.但是自己对jq的选择器又比较依靠,因此尝试着在两晚的时间里自己做一个选择器出来,功能当然也是尽量像jq靠拢. 先大致的整理下自己的思路: 每一次遍历dom元素,每一次遍历到的元素便是下一次遍历到的元素的父级. <div class="firstPapas"><!--第一个父级--> <li class="secondsPapa"><!--第二个父级--> &l

学习小记(2015/10/19)——工作中遇见的一个关于jQuery选择器的小要点。

jQuery是现在非常流行的js库,其中封装了很多很酷炫的功能,其中强大的选择器功能是必不可少的.由于jQuery的选择器,我们能够快速的从许多元素中选中我们需要的目标,从而进行后续的工作.今天,我就讲一下jQuery的我使用jQuery遇见的一个小要点. 当时,我使用jQuery是准备将所有页面上的多选框选中,再对其中某一个进行操作.我是这样做的:HTML: <!DOCTYPE html> <html> <head lang="en"> <m

封装一个类似jquery的ajax方法

//封装一个类似jquery的ajax方法,当传入参数,就可以发送ajax请求 //参数格式如下{ // type:"get"/"post", // dataType:"json"/"jsonp", // url:"地址", // data:{key:value} // success:function(){ // } // } //还需要一个跨域方法,可以访问远程服务器的数据 function myAja

jquery选择器(原创)&lt;二&gt;

jquery选择器,选择接着学: 前面学习了基本选择器中的CSS选择器,现在学层级选择器: 1.子元素选择器 子元素选择器,用于在给定的父元素下,查找这个父元素下面的所有的子元素,语法格式,如下: $("parent>child") 其中,参数parent是任意有效的选择器:child也是一个选择器,并且它是第一个选择器的子元素,用于筛选子元素.两个参数之间,用“>”分隔: <!DOCTYPE html> <html xmlns="http://

原生的html元素选择器的实现,类似jquery选择器

做前端,需要选择元素,虽说有jquery和各大js库已经帮我造好了轮子,但我想试试自己实现一个,正好项目也不忙,正好加入自己的js文件中,下面是实现代码.用$g("#content .op")这种格式就可以调用,和jquery $()的参数一样: 精心开发5年的UI前端框架! function $findChilds(parentNode, text) { //如果不传入父节点的话,默认为body if(parentNode == undefined) parentNode = doc

手动模拟一个类似jquery的ajax请求

1 var $ = { 2 parms:function(obj){ 3 var str = ''; 4 for(var k in obj){ 5 str +=k+'='+obj[k]+'&'; 6 } 7 str = str.slice(0,-1); 8 return str; 9 }, 10 ajax:function(options){ 11 var type = options.type; 12 var url = options.url||''; 13 var data = optio

#PyQuery: 一个类似jQuery的Python库

#出处:http://www.cnblogs.com/QLeelulu/archive/2010/03/05/pyQuery.html#文档:具体的PyQuery文档见:http://pyquery.org/from pyquery import PyQuery as pqd=pq('<html></html>')#直接拼htmld=pq(url='http://www.qq.com')#打开一个urlprint d('title')#获取title元素print d('title

做一个类似JQuery获取DOM对象的$()

在dom操作时,有时根据id获取单个对象.有时根据className获取多个对象.平常可能我们用两个函数来实现这两个功能.不过我将它们整合了一下,目前使用情况良好,函数如下: view source print? 01 // 根据selector获取单个或多个元素, 02 // 获取多个元素时,可以指定元素的tag类型和父元素 03 function $(selector, tag, parent) { 04     var ret = []; 05     06     //没有传递selec

jquery选择器总结2

1.JQuery的概念 JQuery是一个JavaScript的类库,这个类库集合了很多功能方法,利用类库你可以用一些简单的代码实现一些复杂的JS效果. 2.JQuery实现了 代码的分离 不用再网页中加入如:onclick之类的事件来调用函数了,直接引入JQuery类库和自己编写的JQuery代码就可以了:如:$(function(){   $("Element").click{function(){          alert("点击我哦!");     }