• DOM编程艺术--渐进式学习DOM(上)


    什么是DOM?

    • DOM(Document Object Model),直译为文档对象模型

    D, O, M分别是什么?

    • D - document(文档):DOM的作用就是把你的网页文档转换成一个文档对象。这个过程发生在你创建的网页加载到Web浏览器的时候。
    • O - object(对象):正如同window对象对应浏览器窗口本身,其对象的属性和方法统称为BOM,document对象的主要功能就是处理网页内容。这是DOM最常用的对象。
    • M - model(模型):DOM把一份文档表示为一棵树。这棵树由一个个“节点”组成。它的根节点是html

    有哪些节点?

    • 元素节点:可以理解为HTML中的标签。
    • 文本节点:填充元素节点的文本内容。一般为元素节点的第一个子节点。
    • 属性节点:元素的属性也会作为节点。

    获取这些节点的方法有哪些?

    • getElementById( ):返回与id属性对应的对象(一个)。   //文档中每一个元素都是对象
    • getElementByTagName( ):返回有给定标签的对象数组。可以用通配符*返回文档中的每一个元素。
    • getElementByClassName( ):返回给定class的对象数组。可以指定多个类名(用空格分隔),顺序和数量都不重要。

    => id与TagName和ClassName可以搭配使用。

    如何操作属性节点?

    • getAttribute( ):通过属性名字查询。他不通过document,而是通过元素节点对象调用。没有的属性会返回null值。
    • setAttribute( ):不仅能更新已有的属性值,还能设置新属性。

    => 在修改后查看源代码看到的仍是改变前的属性值,setAttribute做出的修改不会反映在文档本身的源代码里。因为DOM的工作模式是先加载文档的静态内容(源文件),再动态刷新(setAttribute在这里发挥作用)。动态刷新不影响文档的静态内容。这也体现了DOM的威力:对页面内容进行刷新却不需要在浏览器中刷新页面。

    一个JavaScript的图片库案例

    这个图片库实例简单应用了刚刚学到的内容。

    gallary.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script type="text/javascript" src="./scripts/showPic.js"></script>
        <link rel="stylesheet" href="./styles/layout.css">
        <title>Gallary</title>
    </head>
    <body>
        <h1>This is a gallary.</h1>
        <ul>
            <li>
                <a href="./images/strawberry.jpg" onclick="showPic(this); return false;" title="This is a kind of delicious fruit.">Strawberry</a>
            </li>
            <li>
                <a href="./images/leaf.jpg" onclick="showPic(this); return false;" title="This is a living leaf.">Leaf</a>
            </li>
            <li>
                <a href="./images/sky.jpg" onclick="showPic(this); return false;" title="This is a really beautiful sky.">Sky</a>
            </li>
        </ul>
        <img id="placeholder" src="./images/placeholder.jpg">
        <p id="description">Choose a picture.</p>
    </body>
    </html>

    showPic.js

    function showPic(whichpic){
        var source = whichpic.getAttribute("href");
        var placeholder = document.getElementById("placeholder");
        placeholder.setAttribute("src", source);
        var text = document.getElementById("description");
        var description = whichpic.getAttribute("title");
        text.firstChild.nodeValue = description;
    }

    效果图:

    知识点拓展

    • return false:事件处理函数中,被调用的JavaScript代码可以返回一个值。比如这里的onClick( )函数,他的返回值是布尔类型的,表示“这个链接是否被点击了”。这里的return false表示让链接显示为未被点击(不打开新的窗口)。
    • childNodes属性:获取一个元素的所有子元素(数组)。返回的数组包含所有类型的节点,甚至包括空格和换行符。
    • 想让函数在页面加载时执行,可以使用onload事件处理函数。
    • nodeType属性:判断获得的节点是哪种属性。他的值是一个数字,元素节点(1)/属性节点(2)/文本节点(3)
    • nodeValue属性:表示文本节点的值。注意元素节点的nodeValue属性为null。文本节点可以表示为对应元素节点的第一个子节点。利用这个可以修改文本节点的值。
    • firstChild和lastChild属性:第一个子节点和最后一个子节点。

    基于性能的考虑--DOM的优化方案

    平稳退化

    即在浏览器不支持JavaScript的时候仍能顺利浏览这个网站。

    比如在图片库例子中,我们考虑需要点击链接打开一个窗口的情况,有几种方法可以实现呢?这些方法可以做到平稳退化吗?

    window.open( ) + "javascript:"伪协议

    window.open(url, name, features),三个参数都是可选的,分别是想要打开网页的地址,新窗口的名字,新窗口的各种属性。

    function popUp(winURL){
        window.open(winURL, "popUp", "width=320, height=480");
    }
    //调用popUp函数
    <a href="javascript:popUp('http://www.example.com');">Example</a>

    这样做在支持伪协议的浏览器中正常运行,较老的浏览器会去试图打开链接但失败,支持伪协议但禁用了JS的浏览器什么都不会做。这显然没有做到平稳退化。

    内嵌的事件处理函数

    <a href="#" onclick="popUp('http://www.example.com'); return false;">Example</a>

    这个例子也没达到平稳退化的效果。如果浏览器禁用了JS,这个链接将毫无作用。

    平稳退化的例子

    首先来了解为什么要追求平稳退化:如果你的网站不能平稳退化,他在搜索引擎的排名会大受损害。

    <a href="http://www.example.com" onclick="popUp(this.href; return false)">Example</a>

    当JS被禁用时这个功能依旧可用,只是被打了点折扣。

    渐进增强

    向CSS学习,将JavaScript与HTML用外部文件的方式分离开来。

    在我们的图片库例子中,内嵌的事件处理函数使得HTML代码中出现了JS,我们需要把他们分离开来。

    var link = document.getElementByTagName("a");
    for (var i=0; i<link.length; i++){
        if(link[i].getAttribute("class") == "popup"){
            link[i].onclick = function(){
                popUp(this.getAttribute("href"));
                return false;
            }
        }
    }

    这样只需要给ul增加一个class属性,就可以把列表中所有a元素的事件处理函数绑定了。

    向后兼容

    需要保证浏览器的能力是否到达可以理解每一行代码的能力。

    对象检测

    用if语句去判断。

    if (!document.getElementByTagName)    return false;

    这个语句表示如果不支持getElementByTagName方式,直接返回false。

    浏览器嗅探技术

    通过浏览器供应商提供的信息来解决向后兼容的问题。但这么做风险很大,浏览器有时会撒谎,嗅探脚本会因为需要适应于多种浏览器而复杂,测试时对版本号的精确要求也使得每次出现新版本就要修改。这种方法已经逐渐被对象检测取代。

    性能考虑

    1. 尽量少的访问DOM和减少标记(过多的元素会增大DOM树的规模,增加遍历DOM以查找特定元素的时间)。
    2. 合并和放置脚本,合并到一个脚本文件中,可以减少加载页面发送请求的数量。这也是性能优化中最先要考虑的。
    3. 压缩脚本文件。

    DOM还能做什么?动态创建标记的开始

    前面学到的方法是对已经存在的元素进行修改,接下来我们可以进一步操纵DOM,利用他创建标记。

    创建标记的传统方法

    document.write

    最大的缺点就是违背了“行为与表现分离”的原则。并且容易导致验证错误。

    <script>
        document.write("<p>This is a inserted.</p>");
    </script>

    <script>后面的<p>很容易被误认为是标签,但这是非法的。实际上这个<p>只是字符串的组成部分而已。

    且MIME类型与document.write不兼容。应该尽量避免使用document.write方法。

    innerHtml属性

    可以读取也可以写入。带标签的情况下,读取是以字符串形式显示的(即标签也显示出来),而写入是以HTML标记语言显示的。使用这个属性会将原有的内容完全覆盖。

    这个方式可以让你不用在<body>中插入<script>,即JS代码从标记中分离出来了。但是仍然不兼容MIME类型。

    DOM方法

    使用DOM方法,你并不是在创建标记,而是在改变DOM节点树。

    createElement方法

    可以创建出一个孤儿节点。这种节点被称为“文档碎片”。他有nodeType属性和nodeName属性(即标记的名称)。还需要把他插入到节点树中去。

    *创建了节点之后立刻赋给一个对象是好习惯哟。

    appendChild方法

    经过这一步,你创建的节点就有了家族关系。但他依旧没有内容。

    parent.appendChild(child);

    createTextNode方法

    可以创建一个文本节点。最后你还需要把文本节点作为被创建元素节点的子节点挂上去哟。

    其他的方法扩展

    insertBefore( ):将一个新元素插到一个现有元素前面。两个参数分别是目标元素,父元素。

    不需要搞清楚父元素究竟是哪一个,只需要使用元素的parentNode属性就好了。

    => DOM并没有给我们提供insertAfter函数,但我们可以利用现有的工具写一个。

    function insertAfter(newElement, targetElement){
        var parent = targetElement.parentNode;
        if (parent.lastChild == targetElement){
            parent.appendChild(newElement);
        }else{
            parent.insertBefore(newElement, targetElement.nextSibling);
        }
    }
  • 相关阅读:
    [PHP]防止表单重复提交的几种方法
    [PHP]PHP的session机制,配置与高级应用
    苹果IOS开发者账号总结--发布应用APP时team name是否可以随意写?
    转:《走出软件作坊》读书笔记
    英语学习技巧摘要
    英语学习规划与目标
    转:人生成功必读的经典语录200条
    转载: PHP错误:Warning: Cannot modify header information
    jQuery Mobile页面返回无需重新get
    mongodb type it for more
  • 原文地址:https://www.cnblogs.com/hermionepeng/p/13255806.html
Copyright © 2020-2023  润新知