zoukankan      html  css  js  c++  java
  • 你不知道的JavaScript--DOM基础详解2

    转载:http://blog.csdn.net/i10630226/article/details/49785165

    先上几张图简要看看DOM的一些方法属性:

    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

    大概这些就是常用的,下面具体聊聊。

    节点类型的判断

    其中元素节点Element的判定最为重要,下面给出4个主要的方法;

    1、如何判断节点是元素节点

    可以用isElement()方法

    <div id="test">aaa</div>
    <!--这是一个注释节点-->
    <script>
    var isElement = function (el){
        return !!el && el.nodeType === 1;
    }
    var a = {
       nodeType: 1
    }
    console.log(isElement(document.getElementById("test")));//true
    console.log(isElement(document.getElementById("test").nextSibling));//false
    
    //但是很容易伪造一个假的“对象节点”
    console.log(isElement(a)); 
    </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    所以要避免这个的伪造,可以重写isElement()方法

    <div id="test">aaa</div>
    <!--这是一个注释节点-->
    <script>
    var testDiv = document.createElement('div');
    var isElement = function (obj) {
        if (obj && obj.nodeType === 1) {//先过滤最简单的
            if( window.Node && (obj instanceof Node )){ //如果是IE9,则判定其是否Node的实例
                return true; //由于obj可能是来自另一个文档对象,因此不能轻易返回false
            }
            try {//最后以这种效率非常差但肯定可行的方案进行判定
                testDiv.appendChild(obj);
                testDiv.removeChild(obj);
            } catch (e) {
                return false;
            }
            return true;
        }
        return false;
    }
    var a = {
       nodeType: 1
    }
    console.log(isElement(document.getElementById("test")));
    console.log(isElement(document.getElementById("test").nextSibling));
    console.log(isElement(a));
    </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2、如何判断节点是html或xml元素节点

    XML与html对象均支持createElement()方法,通过比较创建的元素时传入参数的【大小写】不同的情况下,元素的nodeName是否相同来判断是哪一种文档对象。如果nodeName相同则为html对象,反之为XML对象。

    1、首先看一下Sizzle, jQuery自带的选择器引擎

    //Sizzle, jQuery自带的选择器引擎
    var isXML = function(elem) {
        var documentElement = elem && (elem.ownerDocument || elem).documentElement;
        return documentElement ? documentElement.nodeName !== "HTML" : false;
    };
    console.log(isXML(document.getElementById("test")));
    
    //但这样不严谨,因为XML的根节点,也可能是HTML标签,比如这样创建一个XML文档
    try {
        var doc = document.implementation.createDocument(null, 'HTML', null);
        console.log(doc.documentElement);
        console.log(isXML(doc));
    } catch (e) {
        console.log("不支持creatDocument方法");
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、我们看看mootools的slick选择器引擎的源码:

    var isXML = function(document) {
      return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]')
              || (document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
    };
    
    //精简版
    var isXML = window.HTMLDocument ? function(doc) {
      return !(doc instanceof HTMLDocument);
    } : function(doc) {
      return "selectNodes" in doc;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3、自己实现的方法—最简单

    var isXML = function(doc) {
        return doc.createElement("p").nodeName !== doc.createElement("P").nodeName;
    }
    • 1
    • 2
    • 3

    那接下来判断html节点时,就非常简单了

    var isHTML = function(doc) {
       return doc.createElement("p").nodeName === doc.createElement("P").nodeName;
    }
    console.log(isHTML(document));
    • 1
    • 2
    • 3
    • 4

    3、判断节点间的包含关系:

    现代浏览器可以用contains()方法,aNode.contains(bNode)判断是否包含a>b。

    <div id="p-node">
        <div id="c-node">子节点内容</div>
    </div>
    <script>
        var pNode = document.getElementById("p-node");
        var cNode = document.getElementById("c-node").childNodes[0];
    
        alert(document.contains(pNode));//但是在IE8浏览器不支持
        alert(pNode.contains(cNode));
    </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    但IE不支持文档类型节点和文本类型节点包含关系的判断,可以自定义实现一个兼容各浏览器的判断方法。

    自定义实现fixContains()方法是对这个问题的修复。

      <div id="p-node">
    <div id="c-node">子节点内容</div>
    </div>
    <script>
    //判断节点a包含节点b的方法,即a和b的父节点比较;
    function fixContains(a, b) {
        try {
            while ((b = b.parentNode)){
                if (b === a){
                    return true;
                }
            }
            return false;
        } catch (e) {
            return false;
        }
    }
    var pNode = document.getElementById("p-node");
    var cNode = document.getElementById("c-node").childNodes[0];
    alert(fixContains(pNode, cNode));
    //alert(fixContains(document, cNode));
    </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    节点继承层次与嵌套规则

    1、DOM节点继承层次

    1、文本节点继承层次—-有6层关系

    2、元素节点继承层次—-有7层关系

    console.log(Object.getOwnPropertyNames(document.createElement("p").__proto__));//第一层有两个属性
    console.log(Object.getOwnPropertyNames(document.createElement("p").__proto__.__proto__));//第二层有82个属性
    • 1
    • 2

    1个空div的自有属性有如此之多

    所以就有了现在的一些MVVM框架来管理这些DOM节点层次,比如reactjs 虚拟dom加速。

    2、HTML嵌套规则

    1、块状元素和内联元素

    块状元素

    一般是其他元素的容器,可容纳内联元素和其他块状元素,块状元素排斥其他元素与其位于同一行,宽度(width)高度(height)起作用。

    常见块状元素块级元素—h1,h2,h3,h4,h5,h6,hr,div,fieldset,form,dl,address,ol,p,table,ul,pre

    block元素的特点:

      1. 总是另起一行开始;
      1. 高度,行高以及顶、底边距都可控制;
      1. 宽度缺省是它所在容器的100%,除非设定一个宽度。

    内联元素

    内联元素只能容纳文本或者其他内联元素,它允许其他内联元素与其位于同一行,但宽度(width)高度(height)不起作用。

    常见内联元素为—a,b,br,em,i,img,input,strong,textarea,span,label等常见

    inline元素的特点:

      1. 和其它元素都在一行上;
      1. 高度,行高以及顶、底边距不可改变;
      1. 宽度就是它所容纳的文字或图片的宽度,不可改变。

    他们两个的区别:

    1. 块级元素一般用来搭建网站架构、布局、承载内容
    2. 内联元素一般用来在网站内容中的某些细节或者部位,用以“强调、区分样式、上标、下标、锚点”等等。
    3. 它们可以互相转换。display:inline|block
    4. 块级元素的特点:每一个块级元素都识从一个新行开始显示,其后的元素需要另起一行

    好了 简单地说了一下块级元素和内联元素,下面我们开始我们的重点—–嵌套规则:

    3、嵌套规则

    块级元素可以包含内联元素或某些块级元素,但内联元素不能包含块级元素,它只能包含其它内联元素。
    块级元素不能放在p里面。
    有几个特殊的块级元素只能包含内联元素,不能包含块级元素。如h1,h2,h3,h4,h5,h6,p,dt
    li内可以包含div
    块级元素与块级元素并列、内联元素与内联元素并列。(错误的:<div><h2></h2><span></span></div>

    一张图了解OUTHTML和innerText、innerHTML:

    这里写图片描述

  • 相关阅读:
    IIS配置Asp.net时,出现“未能加载文件或程序集“System.Web.Extensions.Design, Version=1.0.61025.0”
    如何ping测有端口的网站
    职场情况--小领导人品不好,大领导很欣赏我,该不该将小领导的搓事告诉大领导?
    https://www.cnblogs.com/netoxi/p/7258895.html
    java基本数据类型
    不用犹豫什么时候声明实例变量或者拒不变量
    java多线程
    架构考虑
    多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify())
    csrf攻击
  • 原文地址:https://www.cnblogs.com/huangyin1213/p/5908218.html
Copyright © 2011-2022 走看看