Javascript框架思想

       js的学习中,我们总是借鉴或使用jQury,这时候学习前端的工程师们,就想自己封装一个,但是封装属于自己的框架,确实不太容易,所以,jQury使我们很好的一个范本,所以,我i门来研究一下jqury的框架思想,同时自己也可以模仿封装。下面我们学习,封装选择器的思想。

     首先js中的选择器有 id选择器,类(class)选择器和标签选择器。然而在使用id选择器document.getElementById()和标签选择器时document.getElementsByTagName(),这两个属性并没有问题,然而类选择器 document.getElementsByClassName(),但是类选择器并不是所有浏览器兼容,也就是说具有兼容性,所以需要单独对他做处理;首先我们封装一个可以得到id选择器的方法:

function getId(idName) {
//创建一个空数组,将获取的id ,push进数组中存放;
 var result = [];
    var id = document.getElementById(idName);
    if (id != null) {
        result.push(id);
    }
    return result;
}
标签选择器的封装:

//标签
function getTags(tagName) {
    var result = [];
    result.push.apply(result, document.getElementsByTagName(tagName));
    return result;
};

此时将得到的数组也使用了push方法,但是使用了apply();为什么呢?我们简单介绍一下apply方法,

apply() 方法。调用 apply() 方法时,第一个参数是 obj,也就是所要使用的对象,第二个参数是由两个字符串构成的数组,因为document.getElementByClassName()得到的是一个数组,此时你需要的是将得到的数组添加到缓存的数组result中,你需要得到的是标签数组中的每一项,而不是这个数组,apply()的第一个参数是this的指向,就是对象的指向,如果是null的话,那么此时的对象就是window,所以我们必须指明。此时需要注意的是,apply的机制中的第二个参数,内存机制已经对它使用了隐式迭代,所以我们就不必担心遍历的问题。

最后这句代码的意思就是:将得到标签数组的每一个元素添加到result这个对象数组中;

result.push.apply(result, document.getElementsByTagName(tagName));


接下来我们展示类选择器的封装:

var support = {getElementsByClassName: false};

function getClass(className) {
                var result = [];
                if (support.getElementsByClassName === true) {
                    result.push.apply(result, document.getElementsByClassName(className));

                } else {
                   //找到所有的标签;
                    var tags = getTags("*");
                   //遍历所有的标签
                    for (var i = 0, len = tags.length; i < len; i++) {                      
                    var tagClassName = tags[i].className;//"content c2 c3";

                    if (tagClassName) {
                        var changeName = " " + tagClassName + " ";//" content c1 c2 "
                        var chageParam = " " + className + " ";//" content "

                        if (changeName.charAt(chageParam >= 0)) {
                            result.push(tags[i]);
                        }
                    }
                       
                    }
                }
                return result;
            };

看的出来,类选择器比较复杂,因为需要兼容浏览器,看起来比较复杂,接下来,我们就进行分解:

首先我们定义了一个

var support = {getElementsByClassName: false};

这句代码的作用是,我们默认浏览器都不兼容document.getElementsClassName()这个方法,如果浏览器兼容的话,那么直接进行

result.push.apply(result, document.getElementsByClassName(className));
如果不兼容的话,那么我们就需要对他做出兼容处理,首先我们使用了之前封装好的 getTag()方法;使用“*”通配符,得到了页面上所有的标签元素,将返回的数组进行循环遍历,
var tags = getTags("*");
此时我们得到了页面上每一个标签元素,通过判断标签className属性,也就是说我们要找到标签中有 class=“”的元素,
tags[i].className;
如果存在的话,那么我们将对他做出前后添加空格的操作:

 var changeName = " " + tagClassName + " ";//" content c1 c2 "
 var chageParam = " " + className + " ";//" content "

为什么要这样做呢?这只是其中一个简单的方法而已,当然也有其他的方法;我们将所要找的类名 与遍历出来的每一个具有类属性的进行比较,是否出现在遍历出来的元素中,我们需要利用charAt(),判断是否查找得到,

 if (changeName.charAt(chageParam >= 0)) {
        result.push(tags[i]);
    }

以上,我们封装了所有的选择器,但是并不完美,但是我们此时想要达到的效果输入随意的选择器,就可以进行匹配.

很明显我们需要多各个选择器进行判断,id选择器是#开头,类选择器是  "."(点)开头,所以我们需要判断用户输入的字符串特征就可以调用先关的方法,但我们要注意的是,输入的是String字符串,下面我们进行封装:

function $get(selector) {
    var result;
    if (typeof selector === "string") {
        //id:"#content" class:".header" 标签:"p","div"
        // 各类选择器标识不一样,所以要进行判断
        if (selector.charAt(0) === "#") {//此处判断id选择器
            result = getId(selector.slice(1));
        } else if (selector.charAt(0) === ".") {
            result = getClass(selector.slice(1));
        } else {
            result = getTags(selector);
        }

    }
    return result;
}
有的同学已经看到,输入的字符串使用了slice()方法,提取字符串需要的部分,因为此时我们不需要#和点;

以上代码,我们进行了选择器的封装;有很多的不足,例如要进行查找指定元素下的选择器,选择器的分组和层次,

我们都没有完成,后续我们将对他进行再次的优化。













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值