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

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123835 ...
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123835
// DOM框架(选择器框架)
(function (xframe) {
    // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法)
    xframe.extend({
        /**
         * 向现有的元素集合中添加元素节点(修改this的内容)
         * @param dom
         * @return {add}
         */
        add: function (dom) {
            // 1. 项伪数组中添加元素
            this[this.length] = dom;
            // 2. 数组的长度也需要改变了
            this.length++;
            return this;
        },
        /**
         * 向现有的元素节点中添加dom节点(对使用选择器获取的一系列元素都添加孩子节点child)
         * @param child,这里创建的实际上是一个JQuery对象
         */
        append: function (child) {
            // 这里获取的实际上就是只有一个的
            var doms = typeof child === 'string' ? $(child) : $(child[0]),
                arr = Array.prototype.slice.call(doms);
            //console.log(typeof doms[0], typeof arr[0]);
            // 2. 调用自己的方法将一个伪数组转换为数组,并开始遍历
            /*for (var i = 0; i < this.length; i++){
                for (var j = 0; j < doms.length; j++){
                    // 注意这里的操作, 由于在每次添加一个新的元素之后, this的长度就会增加,因此这里在修改之前先把this.length修改一下
                    this[i].appendChild(doms[j]);
                }
            }*/
            /*this.each(function (element) {
                arr.forEach(function (childNode) {
                    element.appendChild(childNode);
                });
            });*/


            // 这里的处理目的是,如果穿过来的DOM节点只是有一个的话需要创建和this长度相同的DOM元素
            if (arr.length !== this.length) {
                arr = [];
                // 相当于是把本身复制几份
                Array.prototype.slice.call(this).each(function () {
                    arr.push(doms[0]);
                });

            }

            // 开始向父亲节点添加元素
            Array.prototype.slice.call(this).forEach(function (element, index) {
                element.appendChild(arr[index]);
            });

            // 开始向我获取的this节点里面添加数据
            /*for (var i = 0; i < this.length; i++){
                for (var j = 0; j < arr.length; j++){
                    if (this[i].childNodes){
                        continue;
                    }
                    // 注意这里的操作, 由于在每次添加一个新的元素之后, this的长度就会增加,因此这里在修改之前先把this.length修改一下
                    this[i].appendChild(arr[j]);
                }
            }*/

        },
        /**
         * 把选择器中的节点添加到父容器中
         * @param parent
         */
        appendTo: function (parent) {
            // 1. 获取所有的父容器
            var doms = $(parent),
                self = this;
            // 2. 向父容器中添加孩子节点
            Array.prototype.slice.call(this).forEach(function (element, index) {
                doms[index].appendChild(self[index]);
            });

            return this;
        },
        /**
         * 获取指定下表下面的DOM节点
         * @param num
         * @return {null}
         */
        get: function (num) {
            return this[num] ? this[num] : null;
        },
        /**
         * 获取一个类似于JQuery的对象实例
         * @param num
         * @return {jQuery|HTMLElement}
         */
        eq: function (num) {
            // 1. 获取一个JQuery对象,首先先获取这个DOM元素节点
            var dom = this.get(num);
            // 2. 把这个DOM节点转换为一个JQuery对象
            return $(dom);
        },
        /**
         * 获取第一个JQuery对象
         * @return {*|jQuery|HTMLElement}
         */
        first: function () {
            return this.eq(0);
        },
        /**
         * 获取最后一个JQuery对象
         * @return {*|jQuery|HTMLElement}
         */
        last: function () {
            return this.eq(this.length - 1);
        },
        /**
         * 获取一个DOM节点的所有子节点
         * @return {array}
         */
        children: function () {
            // 获取一个元素的所有的孩子节点
            // 1. 定义一个伪数组, 用于存储所有的孩子节点, 然后获取默认的第一个元素的所有孩子节点
            var children = this[0].children,
                len = children.length,
                that = {},
                i = 0;

            // 初始化定义的这个伪数组
            that.length = len;
            for (; i < len; i++) {
                that[i] = children[i];
            }

            return that;
        },
        /**
         * 从当前DOM元素节点向下寻找一层元素节点
         * @param str
         * @return {}
         */
        find: function (str) {
            var res = [],
                self = this,
                doms;
            this.each(function () {
                switch (str.charAt(0)) {
                    case '.':
                        // 类选择器
                        doms = $.$class(str.substring(1), self[i]);
                        pushArray(doms);
                        break;
                    default:
                        // 标点选择器
                        doms = $.$tag(str, self[i]);
                        pushArray(doms);
                        break;
                }
            });

            function pushArray(doms) {
                if (doms.length) {
                    self.toArray(doms, function () {
                        res.push(this);
                    });
                }
            }

            // 【注意:】为了能够返回一个JQuery对象,这里需要再次进行处理
            var that = this;
            that.length = this.length;
            this.each(function (index) {
                // 这里需要再次构造一个伪数组对象,从而实现链式访问的功能
                that[index] = res[index];
            });

            // 这里在修改that的时候实际上会间接地把this这个变量修改了
            return that;
        },
        /**
         * 获取一个元素的父类节点
         * @return {parent}
         */
        parent: function () {
            // 获取父节点,并且返回一个JQuery对象
            var parent = this[0].parentNode;
            this[0] = parent;
            this.length = 1;

            // 由于每一个元素只会有一个父类节点,因此长度为1
            return this;

        },
        /**
         * 获取一个元素在同一个级别的元素里面的下表编号
         * @return {number}
         */
        index: function () {
            // 获取元素本身在同一个级别下面的元素下表编号
            var srcNode = this[0],
                children = srcNode.parentNode.children,
                self = this,
                defaultRes = -1;

            self.toArray(children, function (index) {
                // 这里的this指向的就是每一个元素, index指向的就是元素的下表编号
                if (children[index] === srcNode) {
                    defaultRes = index;
                }
            });
            // 返回查询到的结果下标
            return defaultRes;
        }

    });

    // 不需要参与链式访问的
    xframe.extend(xframe, {
        /**
         * 创建一个DOM元素节点
         * @param type
         * @param value
         * @param html
         * @return {*}
         */
        create: function (type, value, html) {
            var dom = document.createElement(type);
            return xframe().add(dom).attr(value).html(html);
        },
        /**
         * 直接的孩子节点
         * @param dom
         * @param tag
         * @return {jQuery|HTMLElement}
         */
        directChildren: function (dom, tag) {
            var res = [],
                tag = tag;
            if (typeof dom === 'string') {
                dom = $(dom);
            }

            // 如果是一个元素集合的处理方法
            if (dom.length) {
                Array.prototype.slice.call(dom).each(function () {
                    getDOM(this.children);
                });
            } else {
                // 如果只是一个元素的处理方法
                getDOM(dom.children);
            }

            /**
             * 主要用于把满足已知条件的DOM元素集合统一放入到一个新的res数组里面去
             * @param doms
             */
            function getDOM(doms) {
                Array.prototype.slice.call(doms).each(function () {
                    if (this.tagName.toLowerCase() === tag.toLowerCase()) {
                        res.push(this);
                    }
                });
            }

            // 如果获得了这个直接子节点,就直接返回这个对象
            return $(res);
        },
    });
})(xframe);

 

相关文章
|
3月前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
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 前端开发
在跨平台虚拟 DOM 框架中处理动画效果
【10月更文挑战第25天】在跨平台虚拟 DOM 框架中处理动画效果需要综合运用多种技术和方法,充分考虑不同平台的特点和性能要求,通过合理的设计和优化,实现高效、流畅且具有良好兼容性的动画效果,从而为用户提供更加丰富和生动的交互体验。
116 63
|
2月前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
2月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
3月前
|
JavaScript 前端开发 API
Vue.js:现代前端开发的强大框架
【10月更文挑战第11天】Vue.js:现代前端开发的强大框架
107 41
|
2月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
73 5
|
2月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
53 2
|
2月前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。