【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);

 

相关文章
|
2月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端框架
【10月更文挑战第34天】在数字化时代,后端开发如同一座桥梁,连接着用户界面与数据处理的两端。本文将通过Node.js这一轻量级、高效的平台,带领读者领略后端框架的魅力。我们将从基础概念出发,逐步深入到实战应用,最后探讨如何通过代码示例来巩固学习成果,使读者能够在理论与实践之间架起自己的桥梁。
|
25天前
|
数据采集 人工智能 自然语言处理
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
Midscene.js 是一款基于 AI 技术的 UI 自动化测试框架,通过自然语言交互简化测试流程,支持动作执行、数据查询和页面断言,提供可视化报告,适用于多种应用场景。
227 1
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
|
2月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
2月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
53 2
|
2月前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
2月前
|
JavaScript 中间件 API
Node.js进阶:Koa框架下的RESTful API设计与实现
【10月更文挑战第28天】本文介绍了如何在Koa框架下设计与实现RESTful API。首先概述了Koa框架的特点,接着讲解了RESTful API的设计原则,包括无状态和统一接口。最后,通过一个简单的博客系统示例,详细展示了如何使用Koa和koa-router实现常见的CRUD操作,包括获取、创建、更新和删除文章。
72 4
|
3月前
|
Web App开发 JavaScript 中间件
构建高效后端服务:Node.js与Express框架的完美结合
【10月更文挑战第21天】本文将引导你走进Node.js和Express框架的世界,探索它们如何共同打造一个高效、可扩展的后端服务。通过深入浅出的解释和实际代码示例,我们将一起理解这一组合的魅力所在,并学习如何利用它们来构建现代Web应用。
92 1
|
2月前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
50 0
|
2月前
|
Web App开发 JavaScript 前端开发
构建高效后端服务:Node.js与Express框架的实践
【10月更文挑战第33天】在数字化时代的浪潮中,后端服务的效率和可靠性成为企业竞争的关键。本文将深入探讨如何利用Node.js和Express框架构建高效且易于维护的后端服务。通过实践案例和代码示例,我们将揭示这一组合如何简化开发流程、优化性能,并提升用户体验。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
2月前
|
Web App开发 JavaScript 中间件
构建高效后端服务:Node.js与Express框架的融合之道
【10月更文挑战第31天】在追求快速、灵活和高效的后端开发领域,Node.js与Express框架的结合如同咖啡遇见了奶油——完美融合。本文将带你探索这一组合如何让后端服务搭建变得既轻松又充满乐趣,同时确保你的应用能够以光速运行。
49 0