JavaScript (五) —— DOM基础

什么是DOM

DOM(Document Object Model)是文档对象模型, 是W3C组织推荐的出来可扩展标记语言(HTML或XML)的标准编程接口
当网页被加载时,浏览器会创建页面的文档对象模型。
W3C 已经定义了一系列的DOM接口, 通过这些DOM接口可以改变网页的内容, 结构, 样式
DOM被结构化为DOM树
在这里插入图片描述

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

DOM把以上内容都看作对象

获取元素

  • 通过id名获取
    document.getElementById('id名') (不加#号)
  • 通过标签获取
    document.getElementsByTagName('元素名')

注意 :

  1. 返回的是获取过来元素对象的集合 以伪数组的形式存储 尽管只有一个或是没有这个元素 都是伪数组形式
  2. 想依次打印里面的元素对象我们可以采取遍历的方式
  3. 还可以获取某个元素(父元素)内部所有指定标签的子元素 element.getElementsByTagName('标签名') 父元素必须是单个对象(必须指明是哪一个元素对象) 获取的不包括父元素自己

遍历 :

        var ul = document.getElementById('ul');
        var lis = ul.getElementsByTagName('li');
        for (var i = 0; i < lis.length; i++) {
            console.log(lis[i]);
        }
  • 通过h5新增方法获取
  1. document.getElementsByClassName('类名') 通过类名获取 括号里不用加'.'
  2. document.querySelector(' ') 返回指定选择器的第一个元素对象 括号里需要加符号 .box #nav
  3. document.querySelectorAll(' ') 返回指定选择器的所有元素对象的集合 伪数组形式
  • 获取body 和 html标签
    document.body 获取body
    document.documentElement 获取html

自定义属性

  • 自定义属性目的 : 是为了保存并使用数据. 有些熟悉可以保存到页面中而不用保存到数据库

  • 设置自定义属性 : 在html 标签里直接写下自定义属性

  • 获取属性值

  1. element.属性 得到的是官方属性值
var div = document.querySelector('div');
console.log(div.id);
  1. element.getAttribute('index') 得到的是程序员自定义的属性
var div = document.querySelector('div');
console.log(div.getAttribute('index'));
  • 重新修改属性值
  1. element.属性 = '新属性值' 修改官方属性值
div.id = 'text';
  1. element.setAttribute('index' , 新属性值) 修改的是程序员自定义的属性值
div.setAttribute('index' , 2);
  • 删除属性
    element.removeAttribute('index')
div.reomveAttribute('index');
  • h5新增自定义属性方法
    dataset 是一个集合 里面存放了所有以data开头的自定义属性
<div data-index = "2" data-last-name = "andy"><div>;
//如果自定义属性有多个连接词 我们获取的时候采取驼峰命名法 并且'data' 不用写
console.log(div.dataset.lastName);
//或者
console.log(div.dataset['lastName']);
//或者
console.log(div.getAttribute('data-last-name'));

事件

- 事件定义

什么是事件
JS使我们有能力创建动态页面 , 而事件使可以被JS侦测到的行为
简单理解 : 触发—相应机制
网页中的每个元素都可以产生某些可以触发JS的事件 , 例如 , 我们可以在用户点击某个按钮时产生一个事件 , 然后去执行某些操作

  • 事件三要素
  1. 事件源 : 事件被触发的对象
  2. 事件类型 如何触发 (比如鼠标经过还是鼠标点击)
  3. 事件处理程序 通过一个函数赋值的方式完成
btn.onclick = function() {
alert('啦啦啦');
}
  • 事件执行过程
  1. 点击事件源
  2. 绑定事件 或者叫注册事件
  3. 添加事件处理程序

- 事件操作

  • 一些常用的绑定事件操作
事件描述
onclick鼠标点击
onmouseover鼠标经过
onmouseout鼠标离开
onfocus获得光标
onblur失去光标
onchange当用户改变输入字段内容时
onmousedown鼠标按下
onmouseup鼠标弹起

更多事件点击这里查看(原生js事件前面都要加on)

  • 事件操作元素(写在function(){}里面的处理程序)
  1. 操作元素内容
    innerHTMLinnerText 都可以获取元素的内容

区别 :
innerText 不识别htnl标签 非标准 去除空格和换行
innerHTML 识别html标签 W3C标准 保留空格和换行
所以我们常使用innerHTML

div.innerHTML = '' //修改
div.innerHTML //获取
  1. 操作常见元素属性

src , href , title , alt
可获取和修改 element.元素属性

  1. 操作表单元素属性

type , value , disabled
可获取和修改 element.元素属性

  1. 操作元素样式属性

我们可以通过js修改元素的大小, 颜色 , 位置等样式
element.style , className

注意 :

  1. js里面的样式采取驼峰命名法 比如 fontSize backgroundColor
  2. js修改style 样式操作 , 产生的是行内样式 , css权重比较高
div.stlye.backgroundColor = 'red';
div.stlye.fontSize = '26px';

当修改的样式多时 可以用classNme
div.className = '类名' (没有 '.')

注意 : 当添加了classNmae之后 就会覆盖原先的类名
要想同时兼顾 我们可以这样写
div.className = 'first change'

节点操作

  • 为什么学节点操作
    前面获取元素的方法
    document.getElementById('id名') , document.getElementByTagName('') , document.querySelector('')
    逻辑性不强 , 繁琐
    利用节点层级关系(父子兄关系)获取元素 逻辑性强 操作简单 但兼容性较差

  • 节点概述

一般, 节点至少拥有nodeType(节点类型) , nodeName(节点名称) 和nodeValue(节点值) 这三个基本属性

  1. 元素节点 nodeType为1
  2. 属性节点nodeType为2
  3. 文本节点 nodeType为3 (包含文字 , 空格 , 换行等)
    实际开发中 , 我们操作的主要是元素节点
  • 父节点
    parentNode 获得的是离元素最近的父级节点(亲爹)
console.log('div.parentNode');
  • 子节点
  1. parentNode.childNodes 返回包含指定节点的子节点的集合 , 该集合为及时更新的集合

注意 :
返回的值里面包含了所有的子节点 , 包括元素节点 , 文本节点 所以 , 如果只想获取里面的元素节点 , 需要专门处理 . 麻烦, 所以我们一般不提倡使用childNodes

特殊处理 :

        var ul = document.querySelector('ul');
        for (var i = 0; i < ul.childNodes.length; i++) {
            if (ul.childNodes[i].nodeType === 1) {
                console.log(ul.childNodes[i]);
            }
        }
  1. firstChild 获取第一个元素 lastChild 最后一个元素 不管是文本节点还是元素节点
  2. firstElementChild 获取第一个元素 lastElementChild 最后一个元素 获取元素节点
  3. children 获取所有的子元素节点 是我们实际开发常用
    我们用children[0]来获取第一个元素
  • 兄弟节点
    node.nextElementSibling 返回当前元素下一个兄弟元素节点 , 找不到就返回null
    node.previousElementSibling 返回当前元素上一个兄弟元素节点 , 找不到就返回null
    注意 : 这两个方法有兼容性问题 IE9以上才支持
  • 创建节点
    var li = document.createElement('li') 创建节点
    父节点.insertBefore(li, 添加到谁前面) 添加节点
    父节点.appendChild(li) 添加节点
//创建一个li
var li = document.createElement('li');
//赋值
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
//添加到里面insertBefore 添加到前面 
ul.insertBefore(li, ul.children[0]);
// ul.appendChild(li);添加到后面

动态创建元素

  1. element.innerHTML 将内容写入某个DOM节点 , 不会导致页面全部重绘 当采取数组形式拼接时(不要拼接字符串) 创建多个元素 与其它方法相比 效率最高 结构稍复杂
  2. document.write() 直接将内容写入页面的内容流 , 但是文档执行完毕 , 它会导致页面重绘
  3. document.createElement() 创建多个元素效率稍低 但结构清晰

数组形式拼接 :

	function fun() {
        var array = [];
        for (var i = 0; i < 1000; i++) {
            array.push('<div>111</div>');
        }
        document.body.innerHTML = array.join('');
    }
    fun();
  • 克隆节点
    node.cloneNode() 括号为空或者是false 浅拷贝 只复制标签不复制里面的内容
    node.cloneNode(true) 括号为true 深拷贝 复制标签和里面的内容
var li = ul.children[0].cloneNode(true);
ul.appendChild(li);
  • 删除节点
    node.removeChild(child) 删除元素
ul.removeChild(ul.children[0]);

监听事件

给元素注册事件 , 称为注册事件或绑定事件 有两种方式
传统方式方法监听注册方式

传统注册方式 :

  1. 利用on开头的事件 (onclick)
  2. <button onclick="alert('hi~')"></button> 或者 btn.onclick = function() {}
  3. 注册事件唯一 同一个元素同一个事件只能设置一个处理函数 , 最后注册的处理函数将会覆盖前面注册的处理函数
  • 事件监听方式 : eventTarget.addEventListener(type, listener[, useCapture])

eventTarget.addEventListener() 方法将指定的监听器注册到eventTarget(目标对象)上 , 当该对象触发指定事件时 , 就会执行事件处理函数

  1. type : 事件类型字符串 , 比如click , mouseover 注意这里不要带on
  2. listener : 事件处理函数 , 事件发生时 , 会调用该监听函数
  3. useCapture : 可选参数 , 是一个布尔值 , 默认是false , DOM事件流之后再详细解释

注意

  1. 监听方法注册事件 是W3C推荐方式 , 但IE9以上才支持
  2. addEventListener() 是一个方法
  3. 特点 : 同一个元素同一个事件可以注册多个监听器 按注册顺序一次执行
  • 传统删除事件 :
div.onclick = function() {
alert(11);
div.onclick = null;
}
  • 监听事件删除
div.addEventListener('click' , fn) // 里面的fn不用调用加小括号
function fn() {
alert(22);
div.removeEventListener('click', fn);
}

事件对象

  • 什么是事件对象 :

官方解释 : event 对象代表事件的状态 , 比如键盘按键的状态 , 鼠标的位置 , 鼠标按钮的状态
简单理解就是 事件发生后 , 跟事件相关的一系列信息数据的集合都放到了这个对象里面 , 这个对象就是事件对象event , 它有很多属性和方法

  • 写法 :
div.addEventListener('click', function(e) {
alert('11');
})

注意 :

  1. event就是一个事件对象 , 写到侦听函数的小括号里面 , 当形参来看
  2. 事件对象只有有了事件才会存在 , 是系统自带的 , 不需要我们传递参数
  3. 这个事件对象我们可以自己命名 比如 event , evt ,e 我们常用e
  4. 事件对象也有兼容性问题
  • 事件对象的常见属性和方法
    在这里插入图片描述

e.targetthis 的区别

  1. e.target 指向的是我们点击的那个对象
  2. this 指向的是我们绑定的那个对象
  3. 在事件委托里 有区分出来
  • 阻止默认行为
    常见的 让链接不跳转 , 或者让提交的按钮不提交
a.addEventListener('click',function(e) {
   e.preventDefault(); //DOM标准写法 有兼容性问题
})
// 我们利用return false 也能阻止默认行为 没有兼容性问题
//特点 : return后面的代码不执行了 , 而且仅限于传统的注册方式

阻止默认行为之 禁用右键 和 禁止选中文字
contextmenu 禁用右键
selectstart 禁止选中文字

	//禁用右键
    document.addEventListener('contextmenu',function(e) {
        e.preventDefault();
    })
    //禁止选中文字
    document.addEventListener('selectstart',function(e) {
        e.preventDefault();
    })

事件对象之键盘事件

几个触发事件的操作

  1. keyup 弹起时触发 (不区分大小写)
  2. keypress 按下时触发 不能触发功能键 比如 ctrl shift (区分大小写)
  3. keydown 按下时触发 能识别功能键 比如 ctrl shift (不区分大小写)
  4. 三个的执行顺序 : keydown - keypress - keyup
  5. 键盘事件对象的一个属性 : keyCode 返回该键的ASCII值 (能区分大小写 会返回不同的ASCII值)
//检测是否按下了s键
    document.addEventListener('keyup',function(e) {
        if (e.keyCode === 83) {
            alert(s);
        }
    })

事件对象之鼠标事件对象

  1. client 鼠标在可视区的x y坐标
  2. page 鼠标在页面文档的x y坐标
  3. screen 鼠标在电脑屏幕的x y坐标
    document.addEventListener('click',function(e) {
        console.log(e.clientX);
        console.log(e.clientY);
        console.log(e.pageX);
        console.log(e.pageY);
        console.log(e.screenX);
        console.log(e.screenY);
    })

事件流

事件流描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播 , 这个传播过程即DOM事件流

DOM事件流分三个阶段

  1. 捕获阶段
  2. 当前目标阶段
  3. 冒泡阶段
    在这里插入图片描述
    事件冒泡 : 事件开始时由最具体的元素接收 , 然后逐级向上传播到DOM最顶层节点的过程

注意 :

  1. JS只能执行捕获或者冒泡其中的一个阶段
  2. onclickattachEvent只能得到冒泡阶段
  3. addEventListener(type, lidtener[, useCapture]) 第三个参数如果时true , 表示在事件捕获阶段调用事件处理程序
    如果是false(默认不写就是false), 表示在事件冒泡阶段调用事件处理程序
  4. 实际开发中我们很少使用事件捕获, 更关注事件冒泡
  5. 有些事件是没有冒泡的 , 比如onblur , onfocus , onmouseenter , onmouseleave
  6. 事件冒泡有时候会带来麻烦 , 有时又会帮助很巧妙的做某些事件
  • 阻止冒泡的兼容性写法
    if(e && e.stopPropagation) {
        e.stopPropagation();
    }else {
        window.event.cancelBubble = true;
    }
  • 冒泡带来的帮助 : 事件委托
    事件委托 又叫事件代理 , 在jQuery里叫事件委派

事件委托原理 : 不是每个子节点单独设置事件监听器 , 而是事件监听器设置在其父节点上 ,然后利用冒泡原理影响设置每个子节点
事件委托好处 : 只操作了一次DOM , 提高了程序的性能

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值