JavaScript进阶之DOM

文档对象模型DOM

文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口。它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式。我们最为关心的是,DOM把网页和脚本以及其他的编程语言联系了起来。DOM属于浏览器,而不是JavaScript语言规范里的规定的核心内容。当网页被加载时,
浏览器会创建页面的文档对象模型(Document Object Model)。
HTML DOM 模型被构造为对象的树。

一、查找元素

1.直接查找

  • document.getElementById 根据ID获取一个标签
  • document.getElementsByName 根据name属性获取标签集合
  • document.getElementsByClassName 根据class属性获取标签集合
  • document.getElementsByTagName 根据标签名获取标签集合

2.间接查找

  • parentNode // 父节点
  • childNodes // 所有子节点
  • firstChild // 第一个子节点
  • lastChild // 最后一个子节点
  • nextSibling // 下一个兄弟节点
  • previousSibling // 上一个兄弟节点

  • parentElement // 父节点标签元素

  • children // 所有子标签

  • firstElementChild // 第一个子标签元素

  • lastElementChild // 最后一个子标签元素

  • nextElementtSibling // 下一个兄弟标签元素

  • previousElementSibling // 上一个兄弟标签元素

节点和标签元素的区别: 节点会把所有元素列出来包括换行符,标签元素只列出标签元素和文本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p id="p1"><span>99999</span></p>
<script>
    var t = document.getElementById('p1')
    var t1 = t.childNodes;
    var t2 = t.children;
    console.log(t1);
    console.log(t2);
</script>
</body>
</html>

效果:

二、操作元素

1.内容

  • innerHTML 设置或获取位于对象起始和结束标签内的 HTML
  • outerHTML 设置或获取对象及其内容的 HTML 形式
  • innerText 设置或获取位于对象起始和结束标签内的文本
  • outerText 设置(包括标签)或获取(不包括标签)对象的文本
  • value 获取input标签的值

innerHTML、outerHTML、innerText、outerText区别:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>innerHTML、outerHTML和innerText、outerHTML的区别</title>
    <script language="JavaScript" type="text/javascript"> 
  //.innerHTML
  function innerHTMLDemo()
  { 
   test_id1.innerHTML="<i><u>设置或获取位于对象起始和结束标签内的 HTML.</u></i>"; 
  } 
  //.innerText
  function innerTextDemo()
  { 
   test_id2.innerText="<i><u>设置或获取位于对象起始和结束标签内的文本.</u></i>"; 
  } 
  //.outerHTML
  function outerHTMLDemo()
  { 
   test_id3.outerHTML="<font size=9pt color=red><i><u>设置或获取对象及其内容的 HTML 形式.</u></i></font>"; 
  }
  //.outerText
  function outerTextDemo()
  { 
   test_id4.outerText="<br></br><i><u>设置(包括标签)或获取(不包括标签)对象的文本.</u></i>"; 
  }
  </script> 
  </head> 
  <body> 
  <ul> 
  <li id="test_id1" onclick="innerHTMLDemo()">innerHTML效果.</li> 
  <li id="test_id2" onclick="innerTextDemo()">innerText效果.</li> 
  <li id="test_id3" onclick="outerHTMLDemo()">outerHTML效果.</li> 
  <li id="test_id4" onclick="outerTextDemo()">outerText效果.</li> 
  </ul> 
  </body> 
  </html>

结果:
请复制代码到此,提交查看:
http://www.w3school.com.cn/tiy/t.asp?f=html_basic

不同之处: 
简单的说innerHTML和outerHTML、innerText与outerText的不同之处在于:
  1)、innerHTML与outerHTML在设置对象的内容时包含的HTML会被解析,而innerText与outerText则不会。
  2)、在设置时,innerHTML与innerText仅设置标签内的文本,而outerHTML与outerText设置包括标签在内的文本。
  
  
value实例:
利用value,搜索框默认显示请输入关键字,当鼠标点击进去之后,删除请输入关键字,当鼠标点击其他地方之后,如果搜索框有内容,则显示输入的内容,没有则继续显示请输入关键字

代码:
  

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <input id="i1" type="text" value="请输入关键字"  onfocus="Foncs()" onblur="Blur()"/>

    <script type="text/javascript">
        function Foncs() {
            var tag = document.getElementById('i1');
            if (tag.value == "请输入关键字") {
                tag.value = '';
            }
        }
        function Blur() {
            var tag = document.getElementById('i1');
            var val = tag.value;
            if (val.trim().length == 0) {
                tag.value = "请输入关键字";
            }

        }
        
    </script>

</body>
</html>

结果:
请复制代码到此,提交查看:
http://www.w3school.com.cn/tiy/t.asp?f=html_basic  
  
  

2.属性

  • attributes // 获取所有标签属性
  • setAttribute(key,value) // 设置标签属性
  • getAttribute(key) // 获取指定标签属性

    全选、反选、取消示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<input type="button" value="全选" onclick="ChoiceALL()"/>
<input type="button" value="取消" onclick="CancleALL()"/>
<input type="button" value="反选" onclick="ReversALL()"/>
<table border="1">
    <thead>
        <tr>
            <td>序号</td>
            <td>用户</td>
            <td>密码</td>
        </tr>
    </thead>
    <tbody id="tb">
        <tr>
            <td>
                <input type="checkbox" />
            </td>
            <td>
                张三
            </td>
            <td>
                123
            </td>
        </tr>

            <td>
                <input type="checkbox" />
            </td>
            <td>
                张三
            </td>
            <td>
                123
            </td>
        </tr>

            <td>
                <input type="checkbox" />
            </td>
            <td>
                张三
            </td>
            <td>
                123
            </td>
        </tr>
    </tbody>

</table>
<script type="text/javascript">
    function ChoiceALL() {
        var tb = document.getElementById('tb');
        var trs = tb.children;
        for (i=0;i<trs.length;i++) {
            var current_tr = trs[i];
            var ck = current_tr.firstElementChild.firstElementChild;
//            ck.setAttribute('checked','checked');
            ck.checked = true;
        }

    }
    function CancleALL() {
        var tb = document.getElementById('tb');
        var trs = tb.children;
        for (i=0;i<trs.length;i++) {
            var current_tr = trs[i];
            var ck = current_tr.firstElementChild.firstElementChild;
//            ck.removeAttribute('checked');
            ck.checked = false;
        }

    }

    function ReversALL() {
        var tb = document.getElementById('tb');
        var trs = tb.children;
        for (i=0;i<trs.length;i++) {
            var current_tr = trs[i];
            var ck = current_tr.firstElementChild.firstElementChild;
            if(ck.checked) {
                ck.checked = false;
            } else {
                ck.checked = true;
            }

        }

    }
</script>
</body>
</html>
3.class 类
  • className // 获取所有类名
  • classList.remove(cls) // 删除指定类
  • classList.add(cls) // 添加类

通过对class类的增删,实现对话框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<style>
        .hide{
            display: none !important;
        }
        .shade{
            position: fixed;
            top:0;
            bottom: 0;
            left: 0;
            right: 0;
            /*background-color: black;*/
            /*opacity: 0.6;*/
            background-color: rgba(0,0,0,.6);
            z-index: 1000;
        }
        .modal{
            height: 200px;
            width: 400px;
            background-color: white;
            position: fixed;
            top: 50%;
            left: 50%;
            margin-left: -200px;
            margin-top: -100px;
            z-index: 1001;
        }
    </style>

    <div style="height: 500px ; 100%">
        <input type="button" value="点我"  onclick="showhide()"/>
    </div>
    <div id="d1" class="shade hide"></div>
    <div id="d2" class="modal hide">
        <a href="javascript:void(0)" onclick="undisplayhide()">取消</a>
    </div>

    <script type="text/javascript">
        function showhide() {
            var d1 = document.getElementById('d1');
            var d2 = document.getElementById('d2');
            d1.classList.remove('hide');
            d2.classList.remove('hide');

        }
        function undisplayhide() {
            var d1 = document.getElementById('d1');
            var d2 = document.getElementById('d2');
            d1.classList.add('hide');
            d2.classList.add('hide');

        }
    </script>
</body>
</html>
4.标签

创建标签

  • 方式1:使用对象创建标签,并添加对应的属性
var tag = document.createElement('a')    创建a标签
tag.innerText = "fuzj"      添加a标签中文本内容
tag.className = "c1"            给a标签应用class c1的样式
tag.href = "http://www.cnblogs.com/pycode"  给a标签添加href属性 
  • 方式2:采用字符串的形式,将标签和属性作为字符串
var tag = "<a class='c1' href='http://www.cnblogs.com/pycode'>fuzj</a>"

操作标签

  • 对象创建方式操作
var d = document.getElementById('d')   //获取要插入的标签
    d.insertAdjacentElement('beforeEnd',tag)
  • 字符串形势操作
var d = document.getElementById('d');   //获取要插入的标签
    d.insertAdjacentHTML('beforeEnd',tag);

插入的位置说明:

  • beforeBegin 在本标签前面添加
  • afterBegin 在本标签的子标签前面添加
  • beforeEnd 在本标签的子标签后面添加
  • afterEnd 在本标签后面添加
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

<div id="d">
    <p>p标签1</p>
    <p>p标签2</p>
</div>
<script>

    var tag1 = "<span>beforeEnd</span>";
    var tag2 = "<span>afterEnd</span>";
    var tag3 = "<span>beforeBegin</span>";
    var tag4 = "<span>afterBegin</span>";
    var d = document.getElementById('d');   //获取要插入的标签
    d.insertAdjacentHTML('beforeEnd',tag1);
    d.insertAdjacentHTML('afterEnd',tag2);
    d.insertAdjacentHTML('beforeBegin',tag3);
    d.insertAdjacentHTML('afterBegin',tag4);


</script>

</body>
</html>

补充:
还有一种方式 添加标签

  • appendChild 添加到指定子节点
  • insertBefore 在现有的子节点前插入一个新的子节点
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

<div id="d">
    <p>p标签1</p>
    <p>p标签2</p>
</div>
<script>

    var tag1 = document.createElement('span');
    var tag2 = document.createElement('span');
    tag1.innerText = 'appendChild';
    tag2.innerText = 'insertBefore';
    var d = document.getElementById('d');   //获取要插入的标签

    d.appendChild(tag1);
    d.insertBefore(tag2,d.childNodes[0]);    //d.choildNodes获取d的所有子节点

</script>

</body>
</html>
5.样式操作

dom对样式操作直接在节点对象后面加.style.对应的样式,注意,类似font-size 变为fontSize,没有了-

var obj = document.getElementById('i1')
obj.style.fontSize = "32px";
obj.style.backgroundColor = "red";

点赞案例:通过循环动态修改样式,实现点赞+1的效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .iterm {
            padding: 50px;
            position: relative;
        }
    </style>
</head>
<body>

<div>
    <div class="iterm">
        <a onclick="zan(this)">赞1</a>
    </div>
    <div class="iterm">
        <a onclick="zan(this)">赞2</a>
    </div>
    <div class="iterm">
        <a onclick="zan(this)">赞3</a>
    </div>
    <div class="iterm">
        <a onclick="zan(this)">赞4</a>
    </div>
</div>

<script type="text/javascript">
    function zan(ths) {
        var top = 50;
        var left = 70;
        var op = 1;
        var fontSize = 18;

        var tag = document.createElement('span')
        tag.innerText = "+1";
        tag.style.position = 'absolute';
        tag.style.top = top + "px";
        tag.style.left = left + "px";
        tag.style.opacity = op;
        tag.style.fontSize = fontSize + "px";
        ths.parentElement.appendChild(tag);
        var interval = setInterval(function() {
            top -= 10;
            left +=10;
            op -= 0.2;
            fontSize +=5;

            tag.style.top = top + "px";
            tag.style.left = left + "px";
            tag.style.opacity = op;
            tag.style.fontSize = fontSize + "px";

            if (op <= 0.2) {
                clearInterval(interval);
                ths.parentElement.removeChild(tag);
            }
        },50)




    }
</script>
</body>
</html>

效果可复制代码至http://www.w3school.com.cn/tiy/t.asp?f=html_basic,进行查看

6.位置操作

  • clientHeight和clientWidth用于描述元素内尺寸,是指 元素内容+内边距 大小,不包括边框(IE下实际包括)、外边距、滚动条部分
  • offsetHeight和offsetWidth用于描述元素外尺寸,是指 元素内容+内边距+边框,不包括外边距和滚动条部分
  • clientTop和clientLeft返回内边距的边缘和边框的外边缘之间的水平和垂直距离,也就是左,上边框宽度
  • offsetTop和offsetLeft表示该元素的左上角(边框外边缘)与已定位的父容器(offsetParent对象)左上角的距离
  • offsetParent对象是指元素最近的定位(relative,absolute)祖先元素,递归上溯,如果没有祖先元素是定位的话,会返回nul
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="divParent" style="padding: 8px; background-color: #aaa; position: relative;">
        <div id="divDisplay" style="background-color: #0f0; margin: 30px; padding: 10px;height: 200px;  200px; border: solid 3px #f00;">
        </div>
    </div>
<script type="text/javascript">
        var div = document.getElementById('divDisplay');
        var clientHeight = div.clientHeight;
        var clientWidth = div.clientWidth;
        div.innerHTML += 'clientHeight: ' + clientHeight + '<br/>';
        div.innerHTML += 'clientWidth: ' + clientWidth + '<br/>';
        var clientLeft = div.clientLeft;
        var clientTop = div.clientTop;
        div.innerHTML += 'clientLeft: ' + clientLeft + '<br/>';
        div.innerHTML += 'clientTop: ' + clientTop + '<br/>';
        var offsetHeight = div.offsetHeight;
        var offsetWidth = div.offsetWidth;
        div.innerHTML += 'offsetHeight: ' + offsetHeight + '<br/>';
        div.innerHTML += 'offsetWidth: ' + offsetWidth + '<br/>';
        var offsetLeft = div.offsetLeft;
        var offsetTop = div.offsetTop;
        div.innerHTML += 'offsetLeft: ' + offsetLeft + '<br/>';
        div.innerHTML += 'offsetTop: ' + offsetTop + '<br/>';
        var offsetParent = div.offsetParent;
        div.innerHTML += 'offsetParent: ' + offsetParent.id + '<br/>';
    </script>
</body>
</html>

效果可复制代码至http://www.w3school.com.cn/tiy/t.asp?f=html_basic,进行查看

其他:

 clientHeight -> 可见区域:height + padding
clientTop    -> border高度
offsetHeight -> 可见区域:height + padding + border
offsetTop    -> 上级定位标签的高度
scrollHeight -> 全文高:height + padding
scrollTop    -> 滚动高度
特别的:
    document.documentElement代指文档根节点

示例:实现随着滚动条滚动,定位菜单:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<style>

    body{
        margin: 0px;
    }
    img {
        border: 0;
    }
    ul{
        padding: 0;
        margin: 0;
        list-style: none;
    }
    h1{
        padding: 0;
        margin: 0;
    }
    .clearfix:after {
        content: ".";
        display: block;
        height: 0;
        clear: both;
        visibility: hidden;
    }

    .wrap{
        width: 980px;
        margin: 0 auto;
    }

    .pg-header{
        background-color: #303a40;
        -webkit-box-shadow: 0 2px 5px rgba(0,0,0,.2);
        -moz-box-shadow: 0 2px 5px rgba(0,0,0,.2);
        box-shadow: 0 2px 5px rgba(0,0,0,.2);
    }
    .pg-header .logo{
        float: left;
        padding:5px 10px 5px 0px;
    }
    .pg-header .logo img{
        vertical-align: middle;
        width: 110px;
        height: 40px;

    }
    .pg-header .nav{
        line-height: 50px;
    }
    .pg-header .nav ul li{
        float: left;
    }
    .pg-header .nav ul li a{
        display: block;
        color: #ccc;
        padding: 0 20px;
        text-decoration: none;
        font-size: 14px;
    }
    .pg-header .nav ul li a:hover{
        color: #fff;
        background-color: #425a66;
    }
    .pg-body{

    }
    .pg-body .catalog{
        position: absolute;
        top:60px;
        width: 200px;
        background-color: #fafafa;
        bottom: 0px;
    }
    .pg-body .catalog.fixed{
        position: fixed;
        top:10px;
    }

    .pg-body .catalog .catalog-item.active{
        color: #fff;
        background-color: #425a66;
    }

    .pg-body .content{
        position: absolute;
        top:60px;
        width: 700px;
        margin-left: 210px;
        background-color: #fafafa;
        overflow: auto;
    }
    .pg-body .content .section{
        height: 500px;
        border: 1px solid red;
    }
</style>
<body onscroll="ScrollEvent();">
<div class="pg-header">
    <div class="wrap clearfix">
        <div class="logo">
            <a href="#">
                <img src="http://core.pc.lietou-static.com/revs/images/common/logo_7012c4a4.pn">
            </a>
        </div>
        <div class="nav">
            <ul>
                <li>
                    <a  href="#">首页</a>
                </li>
                <li>
                    <a  href="#">功能一</a>
                </li>
                <li>
                    <a  href="#">功能二</a>
                </li>
            </ul>
        </div>

    </div>
</div>
<div class="pg-body">
    <div class="wrap">
        <div class="catalog" id="catalog">
            <div class="catalog-item" auto-to="function1"><a>第1张</a></div>
            <div class="catalog-item" auto-to="function2"><a>第2张</a></div>
            <div class="catalog-item" auto-to="function3"><a>第3张</a></div>
        </div>
        <div class="content" id="content">
            <div menu="function1" class="section">
                <h1>第一章</h1>
            </div>
            <div menu="function2" class="section">
                <h1>第二章</h1>
            </div>
            <div menu="function3" class="section" style="height: 200px;">
                <h1>第三章</h1>
            </div>
        </div>
    </div>

</div>
    <script>
        function ScrollEvent(){
            var bodyScrollTop = document.body.scrollTop;
            if(bodyScrollTop>50){
                document.getElementsByClassName('catalog')[0].classList.add('fixed');
            }else{
                document.getElementsByClassName('catalog')[0].classList.remove('fixed');
            }

            var content = document.getElementById('content');
            var sections = content.children;
            for(var i=0;i<sections.length;i++){
                var current_section = sections[i];

                // 当前标签距离顶部绝对高度
                var scOffTop = current_section.offsetTop + 60;

                // 当前标签距离顶部,相对高度
                var offTop = scOffTop - bodyScrollTop;

                // 当前标签高度
                var height = current_section.scrollHeight;

                if(offTop<0 && -offTop < height){
                    // 当前标签添加active
                    // 其他移除 active

                    // 如果已经到底部,现实第三个菜单
                    // 文档高度 = 滚动高度 + 视口高度

                    var a = document.getElementsByClassName('content')[0].offsetHeight + 60;
                    var b = bodyScrollTop + document.documentElement.clientHeight;
                    console.log(a+60,b);
                    if(a == b){
                        var menus = document.getElementById('catalog').children;
                        var current_menu = document.getElementById('catalog').lastElementChild;
                        current_menu.classList.add('active');
                        for(var j=0;j<menus.length;j++){
                            if(menus[j] == current_menu){

                            }else{
                                menus[j].classList.remove('active');
                            }
                        }
                    }else{
                        var menus = document.getElementById('catalog').children;
                        var current_menu = menus[i];
                        current_menu.classList.add('active');
                        for(var j=0;j<menus.length;j++){
                            if(menus[j] == current_menu){

                            }else{
                                menus[j].classList.remove('active');
                            }
                        }
                    }




                    break;
                }

            }


        }
    </script>
</body>
</html>

7.js提交表单

表单form 提交的时候需要使用typ=submit的元素,我们还可以使用js,实现提交表单
document.geElementById('form').submit()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form id="f1">
    <input id="inp" type="text">
    <input  type="submit" value="提交">
    <a onclick="dianji()">提交</a>
</form>

<script>
    function dianji() {
        var fm = document.getElementById('f1');
        var inp = document.getElementById('inp');
        if (inp.value.length > 0) {
            fm.submit();
        } else {
            alert('不能为空')
        }

    }
</script>
</body>
</html>

8.其他操作

console.log 输出框,在chrome开发视图的console下输出
alert 弹出框。
confirm 确认框 弹出是否确认,

// URL和刷新
location.href 获取URL
location.href = "url" 重定向
location.reload() 重新加载

// 定时器
setInterval 多次定时器
clearInterval 清除多次定时器
setTimeout 单次定时器
clearTimeout 清除单次定时器

三.事件

属性当以下情况发生时,出现此事件
onabort 图像加载被中断
onblur 元素失去焦点
onchange 用户改变域的内容
onclick 鼠标点击某个对象
ondblclick 鼠标双击某个对象
onerror 当加载文档或图像时发生某个错误
onfocus 元素获得焦点
onkeydown 某个键盘的键被按下
onkeypress 某个键盘的键被按下或按住
onkeyup 某个键盘的键被松开
onload 某个页面或图像被完成加载
onmousedown 某个鼠标按键被按下
onmousemove 鼠标被移动
onmouseout 鼠标从某元素移开
onmouseover 鼠标被移到某元素之上
onmouseup 某个鼠标按键被松开
onreset 重置按钮被点击
onresize 窗口或框架被调整尺寸
onselect 文本被选定
onsubmit 提交按钮被点击
onunload 用户退出页面

对于事件需要注意的要点:

  • this
  • event
  • 事件链以及跳出 this标签当前正在操作的标签,event封装了当前事件的内容
原文地址:https://www.cnblogs.com/pycode/p/DOM.html