• jQueryDOM操作模块


    DOM操作模块

    1、复习选择器模块(选择器模块结束)

    • 目的:学而时习之 复习和总结选择器模块

    2、DOM的基本操作方法

    • 目标:回顾DOM操作的基本方法

    3.1 DOM操作 -创建节点

    • 练习 1:创建10个 div 并在里面写上 'div 序号' 加到 body 中
    创建元素:document.createElement()
    创建文本:document.createTextNode();
    
    for(var i = 0; i < 10; i++) {
        var dv = document.createElement("div");
        var txt = document.createTextNode("div" + (i + 1));
        dv.appendChild(txt);
        document.body.appendChild(dv);
    }
    
    • 练习 2:在页面中创建 3 个 div, 设置其边框与颜色以及大小
    for(var i = 0; i < 3; i++) {
        var dv = document.createElement("div");
        dv.className = "c";
    
        document.body.appendChild(dv);
    }
    

    3.2 创建节点存在的痛点

    • 痛点分析:
    1 方法较多需要记忆相关方法完成操作
    2 每次循环都使用 appenChild 会导致每次刷新页面结构,性能低
    
    • 解决思路:
    1 封装函数
    2 采用临时容器存储 DOM 对象,最后一次性加到 body 中
    

    3.2.1 使用 div 作为容器

    • 缺点:会改变文档的层次结构

    3.3 文档片段:DocumentFragment

    • 目标:使用 文档片段 作为临时容器存储目标元素

    3.3.1 DocumentFragment解释

    • 理解:可以把文档片段看作一个容器,用来放DOM对象
    • 语法:var df = document.createDocumentFragment();
    • 特点:
    在作为 appendChild() 方法参数的时候,被追加的是片段的所有
    子节点,而不是片段本身。
    
    使用场景:
    创建一个文档片段,然后将创建的DOM元素插入到文档片段中,最后把文档片段插入到DOM树中(实际插入是文档片段的所有子元素)
    

    3.3.2 使用 fragment 作为容器

    var i, dv, container = document.createDocumentFragment();
    for(i = 0; i < 3; i++) {
        dv = document.createElement("div");
        dv.className = "c";
    
        container.appendChild(dv);
    }
    document.body.appendChild(container);
    

    3.4 使用 innerHTML 创建元素

    • 优势:简单方便,通俗易懂
    var i, s = "";
    for ( i = 0; i < 10; i++ ) {
        s += '<div> ' + i + ' </div>';
    }
    
    document.body.innerHTML = s;
    

    4、简单的性能分析

    • 目标:进行DOM操作的性能分析
    var test = function() {
        var startTime, endTime, 
            i = 0, s = "";
    
        startTime = +new Date();
        for(; i < 10000; i++) {
            s += "<div></div>";
        }
        document.body.innerHTML = s;
        endTime = +new Date();
    
        console.log(endTime - startTime);
    };
    

    5、框架中创建元素的实现

    • 目标:实现类似 $("<div></div>") 的功能

    5.1 封装 cElem 函数

    • 目标:将 html 字符串转化为 DOM对象
    var cElem = function(html) {
        var docFrag = document.createDocumentFragment();
        var dv = document.createElement("div");
        dv.innerHTML = html;
        while(dv.firstChild) {
            docFrag.appendChild(dv.firstChild);
        }
        return docFrag;
    };
    

    5.2 cElem 创建元素节点函数的一些说明

    5.2.1 appendChild的说明

    • 作用:将一个节点插入到指定的父节点的中称为其最后一个子节点
    • 注意:
    如果是页面中已经存在的节点,会把它从当前位置移动到新的元素中去。
    移除原来的节点,放到新的元素中去。
    
    var srcDv = select("#d1")[0],
        tarDv = select("#d2")[0],
        cNodes = srcDv.childNodes,
        len = cNodes.length, i;
    
    for(i = 0; i < len; i++) {
        tarDv.appendChild(cNodes[0]);
    }
    

    5.2.2 fragment的说明

    • 注意:无法直接给 文档片段 设置 innerHTML

    5.3 封装 appendTo 函数

    • 目标:实现追加元素的功能
    • 思路:让函数返回一个自定义对象,用来存储DOM对象和方法
    var cElem = function() {
        // ...
        return {
            element: docFrg,
            appendTo: function(dom) {
                dom.appendChild(this.element);
            }
        };
    };
    

    6、框架整体结构

    • 目标:搭建 itcast 的框架结构 整合数据和方法

    6.1 分析jQuery中方法调用规则

    6.1.1 回顾jQuery的使用方法

    $(html).appendTo()
    $(selector).appendTo()
    $(DOMObj).appendTo()
    $(function() {})
    
    html字符串/选择器/DOM对象/DOM对象数组 。。。
    
    在jQuery中,$ 是一个通用性的函数,会根据传入的不同参数,做不同的处理。
    我们需要的就是这么一个 *通用的函数*
    

    6.1.2 $或者jQuery的一些说明

    • 1 函数调用可以获取DOM对象
    • 2 函数调用可以使用jQuery提供的方法
    • 3 函数调用返回的是一个 jQuery对象
    • 4 jQuery方法最终操作的是DOM对象

    6.2 创建框架核心函数:itcast

    • 目标:创建自己的 itcast 通用函数

    6.2.1 创建框架结构 -返回对象

    • 注意:下面是一些伪代码
    • 劣势:浪费内存
    var itcast = function(selector) {
        var o = {};
        if(selector 是选择器) {
            o = select(selector);
        } else if(selector 是html字符串) {
            o = cElem(selector);
        }
    
        o.appendTo = function() {};
        o.css = function() {};
        // ...
    
        return o;
    };
    

    6.2.2 创建框架结构 -使用构造函数创建对象

    • 目标:将公用的方法或者属性放到原型中
    • 问题:DOM对象放在哪?
    var itcast = function(selector) {
        return new F(selector);
    };
    
    var F = function(selector) {
        if(typeof selector === "string") {
            if(selector.charAt(0) === "<") {
                this.elements = cElem(selector);
            }
        }
    };
    
    F.prototype = {
        constructor: F,
        appendTo: function(dom) {
            dom.appendChild(this.elements);
        }
    };
    
    // 调用
    itcast("<div></div>").appendTo(document.body);
    

    6.2.3 创建框架结构 -改进(修改构造函数)

    • 问题1:一个框架强大与否,与什么有关? 方法
    • 问题2:想让我们的框架变得强大需要给谁添加方法?
    • 问题3:框架在沙箱中的,只暴露itcast如何操作F?
    var itcast = function(selector) {
        return new itcast.prototype.init(selector);
    };
    itcast.fn = itcast.prototype = {
        constructor: itcast,
        init: function(selector) {
    
        }
    };
    itcast.fn.init.prototype = itcast.prototype;
    

    6.3 框架扩展

    • 目标:给框架提供扩展能力而不是修改写好的框架文件
    • 原则:开闭原则(对扩展是开放的,对修改是关闭的)

    6.3.1 常用的模块分类

    • 模块:选择 / DOM / 属性 / 样式 / 事件 / 动画

    6.3.2 创建 extend 函数

    • 目标:通过此方法实现对框架的扩展
    itcast.extend = itcast.fn.extend = function(obj) {
        var k;
        for(k in obj) {
            this[k] = obj[k];
        }
    };
    

    6.3.3 创建 each 函数

    • 目标:将 each 函数利用扩展添加到框架中
    itcast.extend({
        each: function(obj, fn) {
            var i, len = obj.length;
            if( itcast.isLikeArray(obj) ) {
                for(i = 0; i < len; i++) {
                    if( fn.call(obj[i], i, obj[i]) === false ) {
                        break;
                    }
                }
            } else {
                for(i in obj) {
                    if( fn.call(obj[i], i, obj[i]) === false ) {
                        break;
                    }
                }
            }
        }
    });
    

    6.4 创建模块 -类型判断模块

    • 目标:框架中类型判断使用频率高,给框架添加类型判断模块
    • 解释:
    静态成员一般用作工具
    静态成员不需要实例化就可以被调用,不会也不可以调用或操纵非静态成员
    
    itcast.extend({
        isFunction: function(obj) {
            return typeof obj === "function";
        },
        isString: function(obj) {
            return typoef obj === "string";
        },
        isLikeArray: function(obj) {
            return obj && obj.length >= 0;
        },
        isItcast: function(obj) {
            // return !!obj.selector;
            return "selector" in obj;
        },
        isDOM: function(obj) {
            return !!obj.nodeType;
        }
    });
    

    7、创建 appendTo 函数 -完整版

    • 目标:创建一个功能完善的 appendTo 函数完成添加元素的功能

    7.1 参数是DOM对象

    itcast.fn.extend({
        appednTo: function(selector) {
            itcast.each(this.elements, function() {
                selector.appendChild(this);
            });
        }
    });
    

    7.2 参数是id选择器

    itcast.fn.extend({
        appednTo: function(selector) {
            itcast.each(this.elements, function() {
                itcast(selector).elements[0].appendChild(this);
            });
        }
    });
    

    7.3 参数是标签选择器

    • 目标:将多个元素(源)加到多个其他元素(目标)中去
    • 思路:
    itcast.fn.extend({
        appendTo: function(selector) {
            var src = this, tarElem,
                tar = itcast(selector);
    
            itcast.each(tar.elements, function(tarIndex) {
                tarElem = this;
                itcast.each(src.elements, function() {
                    tarElem.appendChild(
                        tarIndex === tar.elements.length - 1 ?
                        this:
                        this.cloneNode(true) 
                    );
                });
            });
        }
    });
    
    itcast("<p></p><p></p>").appendTo("div");
    

    8、整合框架代码

    • 目标:使用沙箱模式封装框架,并对外公开 itcast 函数
  • 相关阅读:
    2019 西安邀请赛 D
    time 库
    字符串处理+格式化输出
    数据类型
    turtle1
    格式问题
    字符串1
    基础操作
    链表去重
    PAT 1093
  • 原文地址:https://www.cnblogs.com/lsy0403/p/5910839.html
Copyright © 2020-2023  润新知