H5基础_6_DOM

文章详细介绍了DOM的概念,包括如何通过ID、标签名和类名获取元素,以及DOM提供的各种方法如改变元素内容、样式和属性。还讨论了事件处理,包括事件源、事件类型和事件处理程序,以及事件冒泡和捕获的概念。此外,还涉及到了节点操作和动态创建元素的方法。

灵魂拷问:

浏览器能干什么?

我能让浏览器干什么?

DOM

API 和WebAPI

webAPI是浏览器提供的一套操作浏览器和页面元素的API(BOM和DOM)

DOM简介

什么是DOM

文档对象模型(Document Object Model 简称DOM)是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。

W3C已经定义了一系列的DOM接口,通过这些接口可以改变网页的内容、结构和样式。

DOM树

  • 文档:一个页面就是一个文档,DOM中使用document表示
  • 元素:页面中所有的标签都是元素 ,DOM中使用element表示
  • 节点:网页中所有的内容都是节点(标签、属性、文本、注释等),DOM中使用node表示

DOM把以上内容都看成对象。

获取元素

根据ID获取

getElementById()

返回Element对象,如果找不到就返回null,注意ID不能以数字开头。

可以用console.dir( element) 查看里面的属性和方法。

根据标签名获取

document.getElementsByTagName(‘li’)

正常返回 HTMLcollection[] 伪数组

获取父元素里面的元素。

父元素.getElementsByTagName(‘li’)

H5提供的新方法获取

document.getElementByClassName(‘box’) 返回数组

document.querySelector 返回指定选择器的第一个元素对象

document.querySelectorAll(‘.box1’) 返回所有对象,返回数组

不考虑兼容性的话,重点推荐querySelector

特殊元素

获取body: document.body

获取html: document.documentElement

事件基础

简单理解: 触发——响应机制

事件三要素:
  1. 事件源 事件被触发的对象(element)
  2. 事件类型 如何触发 什么事件 比如鼠标点击onclick 鼠标经过
  3. 事件处理程序 通过一个函数赋值的方式 完成
<script>
    var btn = document.getElementById('btn');
	btn.onclick = function(){
    	alert('点秋香');
	}
</script>
执行事件的步骤:

获取事件源

注册事件

添加事件处理程序

任何元素都可以注册事件。

常见的鼠标事件

onclick

onmouseover

onmouseout

onfocus 获得焦点

onblur 失去焦点

onmousemove

onmoouseup

onmousedown

事件处理注意

可以用循环给多个元素注册事件处理函数,但是在函数内部要多用this语句来处理。

操作元素

改变元素内容
element.innerText

写的时候innerText不能识别Html标签,会作为普通字符处理。

读的时候会去掉html标签,同事空格和换行也去掉。

var div = document.querySelector('div');
var btn = document.querySelector('#btn');
btn.onclick = function(){
    div.innerText=new Date().getTime();
}
element.innerHtml (重点)

写的时候能识别html标签,w3c推荐。

读的时候保留完整的内容,包括html标签,空格和换行。

var div = document.querySelector('div');
var btn = document.querySelector('#btn');
btn.onclick = function(){
    div.innerText=new Date().getTime();
}

这两个属性都可读可写。

改变元素属性

img.src=‘’

改变元素样式

如果样式比较少: element.style.width=100px;

如果样式比较多 : element.className +=’ more’;

排他思想

注意: 下面的循环用 for in会有问题。 用for in的话,元素个数不止5个。

<body>
    
    <button >按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>


    <script>
        var btns = document.getElementsByTagName('button');
        for(var i=0;i<=btns.length-1;i++){
            console.log(i);
            btns[i].onclick= function(){
                for(var i=0;i<=btns.length-1;i++){
                    btns[i].style.backgroundColor = '';
                }
                this.style.backgroundColor = 'pink';
            }
        }

    </script>
</body>

鼠标移动到表格某一行,就改变背景色突出显示:

<body>
    
    <table>
        <thead>
            <tr>
                <td> 姓名</td>
                <td> 年龄</td>
                <td> 性别</td>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td> 张三</td>
                <td> 20</td>
                <td></td>
            </tr>
            <tr>
                <td> 李四</td>
                <td> 21</td>
                <td></td>
            </tr>
        </tbody>
    </table>


    <script>
        var i = document.getElementById('dd');
     
       
        var trs=document.querySelectorAll('tbody tr');
        for(var i=0;i<trs.length;i++){
            
            trs[i].onmouseover = function(){
                console.log(trs[i]);
                this.style.backgroundColor = 'pink';
            }
            trs[i].onmouseout = function(){
                console.log(trs[i]);
                this.style.backgroundColor = '';
            }
        }
    </script>
</body>
自定义属性的操作

获取属性值:

  • element.属性 : 获取内置属性值
  • element.getAttribute(‘属性’) : 主要获得自定义的属性值

设置属性值:

  • element.属性=‘’
  • element.setAttribute(‘属性’,‘值)

移除属性值:

element.removeAttribute(’属性‘)

H5自定义属性规范:

以data-开头

element.dataset.属性= (兼容性不太好)

节点操作

根据父子兄弟关系获取节点

逻辑性强,兼容性稍差

利用dom提供的方法和利用节点层级关系都可以获取元素,利用节点操作更简单。

节点概述:

一般来说,节点至少拥有nodeType、nodeName、nodeValue这三个基本属性。

元素节点 nodeType=1

属性节点 nodetype =2

文本节点 nodeType=3 (文本包括文字,空格,换行等)

实际研发中,节点操作主要操作的是元素节点

节点操作
1、父级节点

node.parentNode(最近的父节点,亲爸爸,如果找不到父节点,就返回null)

2、子节点

node.childNodes 所有的子节点,包括文本节点,属性节点等。

node.children 获取所有的元素节点(非标准,但是得到各大浏览器的支持。

  • ​ node.firstChild
  • ​ node.lashChild
  • ​ node.firstElementChild 第一个子元素节点
  • ​ node.lastElementChild 最后一个子元素节点

前两个不常用,后面两个兼容性不好,所以还是用node.children.

3、兄弟节点

nextSibling

previousSibling

这两个获得所有的类型节点

nextElementSibing

previousElementSibing

获得元素节点(ie9以上才支持)

4、创建节点

var li=document.createElement(‘li’) 创建节点

li.innerHtml=‘’ 设置节点属性

fatherNode.appendChild(li)

fatherNode.insertBefore(li, node) 插入到指定node的前面

5、删除节点

fatherNode.removeChild()

6、复制节点

node.cloneNode()

括号为空或者false,为浅拷贝,不复制子节点

如果括号内为true,则所有的子节点都会复制

动态生成表格
<body>
    <table>
        <thead>
            <tr>
                <td>姓名</td>
                <td>科目</td>
                <td>成绩</td>
                <td>操作</td>
            </tr>
        </thead>
    </table>

  <script>
    var data=[{
        name:'fatux',
        subject:'语文',
        score:80
    },
    
    {
        name:'zhangsan',
        subject:'语文',
        score:82
       
    },
    {
        name:'lisi',
        subject:'语文',
        score:90
    }
  
];

    var table = document.querySelector('table');
    for(i in data){
        var x=data[i]
        var tr=document.createElement('tr');
        tr.innerHTML ='<td>'+ x.name +'</td>'+'<td>'+ x.subject +'</td>'+'<td>'+ x.score +'</td>'+'<td><a href="javascript:;" >删除</a></td>';
        table.appendChild(tr);
    }

    alldelete = document.querySelectorAll('td a');
    for(var i=0;i<alldelete.length;i++){
        alldelete[i].onclick = function(){
            var node =this.parentNode.parentNode;
            node.parentNode.removeChild(node);
        }
    }

  </script>
</body>
动态创建元素的三种方法

document.write 页面重绘,很少使用

innerhtml 创建多个元素时,拼接字符串,比较费时,如果用数组的形式,那么比createElement要稍微高一些

createElement 效率比较高

    function f1(){
        var d1=+new Date();
        for(var i=0;i<1000;i++){
            document.body.innerHTML +='<a href="javascript:;">百度</a>'
        }
        console.log(+new Date()-d1);
    }

    function f2(){
        var d1=+new Date();
        for(var i=0;i<1000;i++){
            var a= document.createElement('a');
            a.innerHTML='百度';
            a.href='javascript:;'
            document.body.appendChild(a);
            
            
        }
        console.log(+new Date()-d1);
    }

    function f3(){
        var d1=+new Date();
        var arr=[];
        for(var i=0;i<1000;i++){
            arr.push('<a href="javascript:;">百度</a>');
            
        }
        document.body.innerHTML =arr.join('');
        console.log(+new Date()-d1);
    }


    f1();
    f2();
    f3();
                                 

DOM重点核心

对元素有创建,增删改查 属性操作,事件操作。

创建:
  1. document.write
  2. innerHTML
  3. createElement
增:
  1. appendchild
  2. insertbefore
删除
  1. ​ removeChild
  1. 修改元素属性 src href title等
  2. 修改普通元素内容 innerHtml innerText
  3. 修改表单元素 value type disables
  4. 修改元素样式 style className
  1. Dom提供的API方法 getElementById
  2. H5提供的新方法 querySelector
  3. 节点操作 parentNode children previousElementSibling
属性操作
  1. setAttibute
  2. getAttribute
  3. removeAttribute
事件操作:

采取事件源.事件类型=事件处理程序 这种方式

onclick onfocus onblur

事件高级操作

注册事件

有两种方式:

  1. 传统方式 事件源.事件=事件处理函数

    每个元素的每个事件只能有一个事件处理程序, 唯一性

  2. 方法监听注册方式

​ w3c标准 推荐方式

addEventListener(type,listener[,useCapture])

​ 同一个元素同一个事件可以注册多个处理函数。(监听器)

  • type :事件类型字符串,比如click mouseover注意这里不用带on
  • listener: 事件处理函数,事件发生时,会调用该监听函数
  • useCapture: 可选参数,默认是false,学完DOM事件流后,在进一步学习
删除事件(解绑事件)
传统方法

事件源.onclick = null;

新方法

funciton fn(){}

e.addEventListener(‘click’,fn)

e.removeEventListener(‘click’,fn) 注意fn不带小括号

DOM事件流

事件在多层元素中传播的顺序叫事件流 , 事件传播分两个阶段,先从上到下传播(捕获阶段)

触底(最下层的叶子节点)后反弹,然后返回到最上层节点(document) 这叫冒泡阶段。

冒泡阶段:ie最早提出

捕获阶段:网景最早提出

注意:

  • 1 JS代码智能执行捕获或者冒泡中的一个
  • 2 onclick和attchevent 只能执行冒泡阶段的事件
  • 3 addeventlistener 第三个参数为true时, 那么处于捕获阶段
  • 4 实际开发中很少会用捕获阶段,更关注事件冒泡
  • 5 有些事件是没有冒泡的,比如onblur onfocus onmouseenter onmouoseleave
  • 事件冒泡有时候会带来麻烦,有时候又会很巧妙的做某件事。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .father {
            width: 300px;
            height: 300px;
            background-color: blue;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="son"></div>
    </div>

<script>
    var father = document.querySelector('.father');
    var son = document.querySelector('.son');
    son.addEventListener('click',function(){
        alert('i am son');
    },true)

    father.addEventListener('click',function(){
        alert('I am father!');
    },true)
</script>
</body>
</html>
事件对象

div.onclick = function(event){}

event 就是事件对象, 事件对象只有有了事件才会存在,系统自动创建的

兼容性处理:

e=e || window.event

事件对象常见的属性和方法

target 触发事件的对象(可能是this的子元素)

this 绑定事件的对象 (e.currentTarget 跟this类似)

type 事件类型(click,mouseover。。。)

阻止默认行为

(让链接不跳转或者提交按钮不提交)

用addEventListener e.preventDefault();

传统方法 element.onclick 用 e.preventDefault(); 或者return false

阻止事件冒泡

e.stopProgagation()

e.cancelBubble() (ie 6,7,8)

事件委托

不是给每个子节点设置事件监听器,而是事件监听器设置在父节点上,然后利用冒泡原理影响设置每个子节点。

比如: 给ul设置事件处理程序,然后根据target来找到当前点击的对象。

优点: 只操作了一次dom,提高了程序性能。

    var ul = document.querySelector('ul');
    ul.addEventListener('click',function(e){
        var li = e.target;
        console.log(li.innerText);
    });

本质就是将儿子的事件委托给父亲。

右键菜单事件
    document.addEventListener('contextmenu',function(e){
        e.preventDefault();
    })
禁止鼠标选中
    document.addEventListener('selectstart',function(e){
        e.preventDefault();
    })
鼠标事件对象 MouseEvent

clientX clientY 点击事件在可视区的X和Y坐标

pageX pageY 在页面文档的X和Y坐标

screenX screenY 在电脑屏幕的x和y坐标,用的相对较少

移动的天使

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>

        .son {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>
</head>
<body>

<div class="son"></div>

<script>
    son = document.querySelector('.son');
    document.addEventListener('mousemove',function(e){
        console.log(e.screenX,e.screenY);
        son.style.left=e.pageX-50+'px';
        son.style.top =e.pageY-50+'px';
    });


</script>
</body>
</html>
常用的键盘事件

onkeydown (按键按下时触发)

onkeypress(按键松开时触发)(不能识别功能键ctrl shift 箭头)

onkeyup (按键松开时触发)

按下弹起的过程,上面三个事件依次触发。 如果一直按着不送,keydown和keypress会不停的触发

    son = document.querySelector('.son');
    document.addEventListener('keyup',function(e){
        console.log('keyup');

    });

    document.addEventListener('keydown',function(e){
        console.log('keydown');

    });

    document.addEventListener('keypress',function(e){
        console.log('keypress');

    });

keyCode : 按键的ascii码值,

keyup,keydown 不区分大小写

keypress 区分大小写

实际开发过程中,更多的使用keydown和keyup。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值