【JavaScript框架封装】实现一个类似于JQuery的选择框架的封装

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123799 ...
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123799
// 选择框架
(function (xframe) {
    // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法)
    xframe.extend({});


    // 不需要参与链式访问的
    xframe.extend(xframe, {
        /**
         * ID选择器
         * @param context
         * @return {HTMLElement | *}
         */
        $id: function (context) {
            // context是一个DOM对象还是字符串
            context = this.isString(context) ? document.getElementById(context) : context;
            return context;
        },
        /**
         * tag选择器, context;里面存储了上下文信息(尽量少的使用局部变量)
         * @param tag
         * @param context
         * @return {NodeListOf<HTMLElementTagNameMap[keyof HTMLElementTagNameMap]>}
         */
        $tag: function (tag, context) {
            // 分为两种情况
            if (typeof context === 'string') {
                context = this.$id(context);
            }

            // 按照这种思路,只有可能是一种情况
            if (context) {
                if (context.length) {
                    // 这里默认只会返回数组中的第0个元素
                    return [].slice.call(context)[0].getElementsByTagName(tag);
                } else {
                    return context.getElementsByTagName(tag);
                }
            }
            return document.getElementsByTagName(tag);
        },
        /**
         * 实现一个类选择器
         * @param className
         * @param context
         * @return {*}
         */
        $class: function (className, context) {
            // context里面此时存储的是一个DOM节点元素
            // 如果直接传过来的是一个DOM元素节点context(DOM元素的话就单独处理)
            context = this.$id(context) || document;

            // 1.由于getElementByClassName()这个方法是不兼容的,因此需要使用浏览器内置的方法去获取类选择器
            // 2. 可以使用getElementByTagName()的方法去获取所有的标签元素,然后把再使用className的属性间接去实现一个类似的class选择器的功能
            if (context.getElementsByClassName) {
                // 如果支持这个方法的话
                return context.getElementsByClassName(className);
            } else {
                // 不支持的话就间接获取
                var doms = context.getElementsByTagName('*'),
                    res = [];
                // 使用自己定义的方法去实现一个类选择器
                doms.each(function () {
                    if (this.className === className) {
                        // 只要是找到了这个class的集合,就放入到一个数组里面
                        res.push(this);
                    }
                });
                return res;

            }
        },
        /**
         * 使用管道思想实现一个层次选择器
         * @return {Array}
         */
        $cengci: function () {
            var self = this;
            // 主要功能:实现一个层次选择器
            // 输入字符串: str = '#className div  a p'  选择所有的className 下面的P标签
            // 1. 获取穿过来的参数(数组元素去重)
            var args = Array.prototype.slice.call(arguments)[0].toString().split(' '),
                index,
                first,
                item,
                selector,
                res = [],           // 存储了本次的结果信息
                context = [];            // 存储了上一次的上下文信息【管道思想!】, context = 'tag .class #id'


            // 思考: 为了实现一个层次选择器, 如何实现一个吧上一次选择的元素全部存储起来???


            // 2. 开始解析参数信息
            args.each(function () {
                // 每次重复之前,先把本次需要存储的数组清空(res里面存储了每次的最新数据)
                res = [];

                // 对获取到的每一项进行处理
                item = this.trim();
                first = item.charAt(0);
                index = item.indexOf(first);
                selector = item.slice(index + 1);


                // 使用管道思想实现一个层次选择器!!!
                switch (first) {
                    case '.':  // class 选择器
                        if (context.length) {
                            // 说明这一次的class类选择器中的元素不是第一次出现
                            context.each(function () {
                                pushArray(self.$class(selector, this));
                            });
                        } else {
                            // 如果是第一次出现的话
                            pushArray(self.$class(selector));
                        }
                        // 把上一次执行的结果存起来
                        context = res;
                        break;
                    case '#':  // ID选择器
                        // 由于ID选择器获取的元素始终是唯一的,因此直接放进去即可
                        res.push(self.$id(selector));
                        // 把上一次执行的结果存起来
                        context = res;
                        break;
                    default:    // tag选择器
                        if (context.length) {
                            // 说明不是第一次出现
                            context.each(function () {
                                // 注意在使用tag选择器的时候,第二个参数必须是一个ID选择器,或者是一个
                                // 1. 注意在放入数组的时候,需要逐个遍历然后放进去
                                pushArray(self.$tag(item, this));
                            });
                        } else {
                            // 第一次出现的
                            pushArray(self.$tag(item));
                        }
                        // 把上一次执行的结果存起来
                        context = res;
                        break;
                }
            });


            /**
             * 把公共的部分代码封装起来
             * @param doms
             */
            function pushArray(doms) {
                if (doms) {
                    [].slice.call(doms).each(function () {
                        res.push(this);
                    });
                }
            }

            return context;
        },
        /**
         * group选择器
         * @return {Array}
         */
        $group: function () {
            var self = this;
            // '.moshou,#moshou,span,.dream'
            // 1. 获取传过来的参数
            var args = [].slice.call(arguments),
                arr = args[0].split(',').unique(),      // 这里在拿到这个分割后的字符串后,开始进行数组元素去重
                item,
                index,
                first,
                selector;
            res = [];

            // 2. 开始遍历参数集合,解析参数信息
            arr.each(function () {
                // 3. 开始遍历得到结果,获取每一项
                item = this.trim();
                // 4. 开始获取首字母信息,和后面的选择器信息
                // 4. 获取指定下标位置对应的字符
                first = item.charAt(0);
                index = item.indexOf(first);
                selector = item.slice(index + 1);


                // 开始根据第一个字母向下进行判断,把满足相应条件的放在数组里面
                switch (first) {
                    case '.':
                        // class选择器
                        res.push(self.$class(selector));
                        break;
                    case '#':
                        // ID 选择器
                        res.push(self.$id(selector));
                        break;
                    default:
                        // TAG选择器(直接就是first本身,这里不用再判断了使用selector这个变量了)
                        res.push(self.$tag(item));
                        break;
                }
            });

            return res;
        },
        /**
         * 多组+层次选择器
         * @return {Array}
         */
        $select: function () {
            // str = '#tag , .calss'
            var args = [].slice.call(arguments)[0].toString().split(','),
                ret = [],
                self = this;

            // 遍历args数组,对数组的每一项采用层次选择器
            args.each(function () {
                // 1. 对于逗号分隔的部分采用层次选择,获取层次选择器的结果信息, 是一个数组集合
                var res = self.$cengci(this);
                // 2. 遍历层次选择器的集合,把信息放入到一个新的数组里面, 就是得到的多组选择器的结果信息
                pushArray(res);
            });


            // 层次选择器
            function pushArray(doms) {
                if (doms.length) {
                    doms.each(function () {
                        ret.push(this);
                    });
                }
            }

            return ret;
        }
    });
})(xframe);

 

相关文章
|
17天前
|
开发框架 JavaScript 安全
js开发:请解释什么是Express框架,以及它在项目中的作用。
【4月更文挑战第24天】Express是Node.js的Web开发框架,简化路由管理,支持HTTP请求处理。它包含中间件系统用于日志、错误处理和静态文件服务,集成多种模板引擎如EJS、Jade、Pug。框架还提供安全中间件提升应用安全,并具有良好的可扩展性,便于项目功能扩展和开发效率提升。
25 3
|
3天前
|
JavaScript 前端开发
JS实现网页页面的框架(demo)
JS实现网页页面的框架(demo)
9 1
|
9天前
|
JavaScript 前端开发 C++
【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
【5月更文挑战第2天】【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
|
9天前
|
设计模式 前端开发 JavaScript
AngularJS是一款由Google收购的JavaScript结构框架
AngularJS是Google收购的JavaScript框架,用于构建动态Web应用,基于MVC模式,强调模块化和双向数据绑定。它简化了视图与模型的同步,通过语义化标签和依赖注入提升开发效率。适用于复杂单页面应用(SPA),但不适合DOM操作密集型或性能要求极高的场景。
17 0
|
11天前
|
JavaScript 前端开发 IDE
【JavaScript与TypeScript技术专栏】TypeScript在JavaScript库与框架开发中的作用
【4月更文挑战第30天】TypeScript,微软开发的JavaScript超集,以其强类型和面向对象特性,正成为提升Web项目质量和效率的关键工具,尤其在库和框架开发中。它通过类型系统减少运行时错误,提供内置文档,便于重构,增强IDE支持,以及支持模块化。流行框架如React、Angular已支持TypeScript,未来有望成为开发高质量库和框架的标准语言。随着社区增长,TypeScript将在Web开发领域扮演更重要角色。
|
11天前
|
开发框架 JavaScript 中间件
深入探索Node.js的Express框架:使用与中间件详解
【4月更文挑战第30天】本文深入探讨了Node.js的Express框架,介绍了其作为Web开发的强大工具,主要聚焦于基本使用和中间件。Express是基于Node.js的Web应用框架,用于构建高效的应用和API。文章详细讲解了如何安装Express,创建简单应用,以及中间件的工作原理和应用,包括中间件的顺序、错误处理和挂载位置。此外,还提到了使用第三方中间件扩展功能。理解Express基础和中间件对于开发高质量Web应用至关重要。
|
12天前
|
JavaScript 前端开发 开发者
前端框架(Vue.js&&vue-cli项目框架&&element-ui使用)
前端框架(Vue.js&&vue-cli项目框架&&element-ui使用)
|
23天前
|
JavaScript 前端开发 API
JavaScript和jQuery的区别
JavaScript和jQuery的区别
|
24天前
|
JavaScript 前端开发 API
js和jquery的区别
js和jquery的区别
16 8
|
Web App开发 JavaScript 前端开发
《jQuery与JavaScript入门经典》——2.7 问与答
就Cookie调试而言,您只需知道是否启用了Cookie、浏览器设置了哪些Cookie、这些Cookie的值是什么以及它们什么时候到期。这些信息都可在Firebug的Cookies选项卡中找到。Chrome和Internet Explorer在开发人员控制台中提供了类似的功能。
1131 0