15-JS封装:入口函数

目录

1 模块化的基本结构

2 编写封装里的jQuery函数

2.1 对象本身上添加css方法

 2.2 对象原型上添加css方法

2.3 自定义构造函数 

2.4 优化1-伪数组

2.5 优化2-原型链

 2.6 简化代码


需求:给页面中所有的div设置字体颜色为红色

jQuery封装:$("div").css("color","red")

如果没有引入jQuery,该如何编写?

1 模块化的基本结构

要封装的这个库应该是一个独立的单元:模块化

独立:

  1. 不依赖任何其他第三方库
  2. 里面的东西大部分也是与世隔绝的,只有:$、jQuery

模块化的基本结构

    (function (global) {

        function jQuery() {

        }

        //global.$ = global.jQuery = jQuery;

        //相当于:
        global.jQuery = jQuery;
        global.$ = jQuery;
    })(window)

1) 传入window,global接收window,即global保存了window对象的引用

2)在global(相当于window)里添加一个方法jQuery,并将模块化里的jQuery函数将其赋值

3)在global(相当于window)里添加一个方法$,并将模块化里的jQuery函数将其赋值

2 编写封装里的jQuery函数

2.1 对象本身上添加css方法

步骤:

1、获取页面中所有的元素
2、把这个元素放在一个特定的对象中

观察$("div").css("color","red")所得:

直接在jQuery函数里elementsc添上css方法

(function(global){

        function jQuery(selector){

            const elements = document.getElementsByTagName(selector);
            elements.css=()=>{

            }
            return elements;
        }

        window.$ = window.jQuery = jQuery;
    })(window)

    
    $("div").css()
    $("p")
    $("span")
    $("img")
    $("input")

 问题:随着$()操作频次的增加,会产生无数个相同的css方法,造成内存浪费

 2.2 对象原型上添加css方法

放在对象本身上会造成浪费,则我们优化成:放在对象的原型上 

(function(global){

        function jQuery(selector){

            const elements = document.getElementsByTagName(selector);
            return elements;
        }

 
        HTMLCollection.prototype.css=()=>{
            console.log('css方法');
        }

        window.$ = window.jQuery = jQuery;
    })(window)

    $("div").css()

这种解决方案,把DOM操作的方法都放在了原型中,这样看似可以正常访问,但是依然存在问题:破坏了原生的对象结构

2.3 自定义构造函数 

自定义构造函数 F,在F的原型上添加css方法

<body>
    <div>aaa</div>
    <div>bbb</div>
    <div>ccc</div>

    <span class="header">123</span>
    <input type="text" id="inputId">
</body>
<script>
    //给页面中所有的div设置字体颜色为红色
    //$("div").css("color","red")

    (function(global){
        function jQuery(selector){

            return new F(selector);
        }

        //jquery对象的构造函数
        function F(selector){
            //jquery内部封装了一个Sizzle引擎来获取DOM元素
            
            const elements = document.querySelectorAll(selector) //把DOM元素放到这个对象中
           
            this.elements = elements; //为了让这些元素可以在css方法中进行访问,所以需要把这些元素放在对象上面进行传递
        }

        F.prototype.css=function(name,value){
            for(let i = 0;i<this.elements.length;i++){
                let element = this.elements[i];
                element.style[name]=value;
            }
        }
   
        window.$ = window.jQuery = jQuery;
    })(window)

    
    $("div").css("color","red")
    $(".header").css("backgroundColor","pink")
    $("#inputId").css("backgroundColor","black")
</script>

2.4 优化1-伪数组

    jquery为了后续的DOM操作的方便,将这些获取到的DOM元素全部放在了对象自己身上,让自己变成了一个就像数组一样,可以使用for循环进行遍历,我们把这种对象特性称之为【伪数组】

(function(global){

        function jQuery(selector){

            return new F(selector);
        }
        
        function F(selector){
            //把DOM元素放到这个对象中
            const elements = document.querySelectorAll(selector)

            //实现把这些所有DOM元素都添加到对象自己身上
            for(let i = 0;i<elements.length;i++){
                //ele:DOM元素
                this[i] = elements[i];
            }
            this.length=elements.length;
            
        }

        F.prototype = {
            constructor:F,
            //此时的css方法还是雏形,后续完善
            css(name,value){
                for(let i = 0;i<this.length;i++){
                    let element = this[i];
                    element.style[name]=value;
                }
            }
        }

        window.$ = window.jQuery = jQuery;
    })(window)

    
    $("div").css("color","red")
    $(".header").css("backgroundColor","pink")
    $("#inputId").css("backgroundColor","black")

    //实现的结果:没次需要new一个对象,但是对象的方法是共用的
    var $1=$("div");
    var $2=$("div");
    console.log($1 == $2); //2个对象,false
    console.log($1.css == $2.css); //同一个方法,true

优化前

 

优化后

jquery对象不可能相同,后续,内存优化介绍如何适当地解决这种jquery对象消耗的内存

2.5 优化2-原型链

1、jQuery函数里返回的是构造函数(jQuery原型里的init函数)

2、jQuery原型里有的css函数

3、jQuery.prototype.init(selector)只能访问本身及其原型里的内容(原型:构造函数.prototype)

4、所以 jQuery.prototype.init.prototype = jQuery.prototype;

<script>
    (function(global){

        function jQuery(selector){

            var _init=jQuery.prototype.init;
            return new _init(selector);
            
            //等价于:
            //return new jQuery.prototype.init(selector);
        }

        jQuery.prototype = {
            constructor:jQuery,
            init:function(selector){
              
                const elements = document.querySelectorAll(selector)

                for(let i = 0;i<elements.length;i++){
                    this[i] = elements[i];
                }
                this.length=elements.length;
                
            },
           
            css(name,value){
                for(let i = 0;i<this.length;i++){
                    let element = this[i];
                    element.style[name]=value;
                }
            }
        }

        //此时创建的jquery是init构造函数的实例
        //css方法在jquery.prototype对象中
        //-->为了让jquery对象可以访问到css方法
        //  -->让init的原型继承自jQuery.prototype

        jQuery.prototype.init.prototype = jQuery.prototype;

        //-->1、创建了一个init的对象
        //-->2、执行css方法
        //  -->找对象本身有没有css方法,并没有
        //  -->找对象的原型:init.prototype -->jquery.prototype
        //  -->发现jquery.prototype中有一个css方法

        

        window.$ = window.jQuery = jQuery;
    })(window)

    
    $("div").css("color","red")
    $(".header").css("backgroundColor","pink")
    $("#inputId").css("backgroundColor","black")

    var $1=$("div");
    var $2=$("div");
    console.log($1 == $2); //2个对象,false
    console.log($1.css == $2.css); //同一个方法,true

</script>
 2.6 简化代码

1、考虑到需要经常访问jQuery.prototype

2、给jQuery添加了一个fn属性,fn属性等价于prototype属性

3、访问jQuery.fn相当于访问jQuery.prototype

(function(global){

        function jQuery(selector){

            return new jQuery.fn.init(selector);
        }
        
        //给jquery添加了一个fn属性,fn属性等价于prototype属性
        jQuery.fn = jQuery.prototype = {
            constructor:jQuery,
            init:function(selector){
                
                const elements = document.querySelectorAll(selector)

                for(let i = 0;i<elements.length;i++){
                    this[i] = elements[i];
                }
                this.length=elements.length;
                
            },
            
            css(name,value){
                for(let i = 0;i<this.length;i++){
                    let element = this[i];
                    element.style[name]=value;
                }
            }
        }

        
        jQuery.fn.init.prototype = jQuery.fn;

        window.$ = window.jQuery = jQuery;
    })(window)

 
  • 42
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
封装一个全局的函数式组件,你可以遵循以下步骤: 1. 在 `src` 目录下创建一个新的文件夹,例如 `components`,并在该文件夹中创建一个名为 `ElDialog.vue` 的文件。 2. 在 `ElDialog.vue` 文件中编写组件的代码,如下所示: ```html <template> <div v-if="visible" class="el-dialog"> <h2 class="el-dialog-title">{{ title }}</h2> <p class="el-dialog-content">{{ content }}</p> <!-- 其他内容... --> </div> </template> <script> import { defineComponent, reactive } from 'vue'; export default defineComponent({ name: 'ElDialog', props: { title: String, content: String, // 其他 props... }, setup(props) { const visible = reactive({ value: false }); return { visible, }; }, }); </script> <style scoped> .el-dialog { /* 样式定义 */ } .el-dialog-title { /* 样式定义 */ } .el-dialog-content { /* 样式定义 */ } </style> ``` 在上述代码中,我们使用了 `reactive` 函数来创建响应式数据 `visible`,用于控制组件的显示与隐藏。通过在父组件中修改 `visible.value` 的值,可以控制 `el-dialog` 的显示状态。 3. 在 `src` 目录下创建一个名为 `main.js` 的文件,并在其中注册全局的函数式组件: ```javascript import { createApp } from 'vue'; import ElDialog from './components/ElDialog.vue'; const app = createApp(); app.component('el-dialog', ElDialog); app.mount('#app'); ``` 在上述代码中,我们使用 `app.component` 方法来注册 `el-dialog` 组件为全局组件。这样,在你的应用程序的任何地方,你都可以使用 `<el-dialog>` 标签来引用该组件。 4. 在你的应用程序的主入口文件中,例如 `App.vue`,使用 `<el-dialog>` 标签来调用该组件: ```html <template> <div id="app"> <!-- 其他内容... --> <el-dialog title="对话框标题" content="对话框内容"></el-dialog> </div> </template> <script> export default { // 组件的逻辑... }; </script> <style> /* 样式定义... */ </style> ``` 现在,你就可以在整个应用程序中使用 `<el-dialog>` 标签,并传递所需的属性来显示全局的函数式组件了。 请注意,以上示例只是一个简单的演示,你可以根据实际需求进行更复杂的组件逻辑和样式定义。同时,也可以根据项目的具体情况,在全局注册组件时使用其他的标签名。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mikuc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值