1. DOM
学习视频:https://www.bilibili.com/video/BV1Sy4y1C7ha/
-
DOM简介
-
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
-
通过这些 DOM 接口可以改变网页的内容、结构和样式。
-
DOM树:
- 文档:一个页面就是一个文档,DOM 中使用 document 表示
- 元素:页面中的所有标签都是元素,DOM 中使用 element 表示
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示
- DOM 把以上内容都看做是对象
-
-
获取元素
-
原因:DOM在开发中主要用来操作元素
-
如何获取
-
根据 ID 获取
document.getElementById( );
- 在MDN搜索
document.getElementById( );
可得详细信息 - 作用:可以获取返回带有 ID 的元素对象
- 可以
console.dir()
使用打印元素对象,比console.log()
好观察
<div id="time">2019-9-9</div> <script> // 1. 因为我们文档页面从上往下加载,所以先得有标签 所以我们script写到标签的下面 // 2. 参数 id是大小写敏感的字符串 var timer = document.getElementById('time'); console.log(timer); console.log(typeof timer);//object所以返回的是一个元素对象 // 3. console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法 console.dir(timer); </script>
- 在MDN搜索
-
根据标签名获取
getElementsByTagName()
-
作用:返回带有指定标签名的对象的集合
-
返回:获取过来元素对象的集合以伪数组(有长度等但是没有push、pop等方法)的形式存储的
-
就算是只有一个li也是伪数组,如果页面中没有li这个元素,返回的是空的伪数组的形式
-
得到元素对象是动态的,根据内容而变
-
获取1 :所有的都获取过来
document.getElementsByTagName('标签名')
<ul> <li>知否知否,应是等你好久11</li> </ul> <script> // 1.返回的是 获取过来元素对象的集合 以伪数组的形式存储的 var lis = document.getElementsByTagName('li'); console.log(lis);//得到的是个集合 console.log(lis[0]);//第一个li // 2. 我们想要依次打印里面的元素对象我们可以采取遍历的方式 for (var i = 0; i < lis.length; i++) { console.log(lis[i]); } </script>
-
获取2:获取某个父元素内部所有指定标签的子元素
element.getElementsByTagName('标签名')
,注意:父元素必须是单个对象(document.getElementsByTagName()返回的伪数组不能作为父元素,因为必须指明是哪一个元素对象),获取时不包括父元素自己。组<ol id="ol"> <li>生僻字</li> </ol> <script>//如果有ol也有ul //写法1: var ol = document.getElementsByTagName('ol'); // [ol]这个伪数组不是指定某个元素不能作为父元素 console.log(ol[0].getElementsByTagName('li'));//这样是可以指定的 //console.log(ol.getElementsByTagName('li'))//这样是不行的,伪元素不能作为父元素 //写法2: var oll = document.getElementById('ol');//用这个方法直接把ol这个元素获取到 console.log(oll.getElementsByTagName('li'));//拿它下面的li </script>
-
-
通过 HTML5 新增的3个元素获取方法
-
根据类名返回元素对象集合:
document.getElementsByClassName(‘类名’);
<div class="box">盒子1</div> <div class="box">盒子2</div> <script> // 1. getElementsByClassName 根据类名获得某些元素集合 var boxs = document.getElementsByClassName('box'); console.log(boxs);//伪数组的形式,存了两个box
-
根据指定选择器返回第一个元素对象:
document.querySelector('选择器');
里面的选择器需要加符号 .,#var firstBox = document.querySelector('.box');//加.识别类选择器 console.log(firstBox); var nav = document.querySelector('#nav');//#识别为id选择器 console.log(nav); var li = document.querySelector('li');//li不用加符号 console.log(li);//只有返回第一个li
-
返回指定选择器的所有元素对象集合:
querySelectorAll()
var allBox = document.querySelectorAll('.box'); console.log(allBox);//输出所有的box var lis = document.querySelectorAll('li'); console.log(lis);//输出所有的li
-
-
获取特殊元素
-
获取body元素,返回元素对象
document.body
var bodyEle = document.body; console.log(bodyEle);//返回元素对象 console.dir(bodyEle);//返回元素对象
-
获取html元素
document.documentElement
var htmlEle = document.documentElement; console.log(htmlEle);
-
-
-
补充:
console.dir()
用于以更详细的方式显示 JavaScript 对象(包括 DOM 元素)的属性和方法。
-
-
事件基础
-
触发— 响应机制,网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。
-
事件三元素(事件的组成):
- 事件源 (谁)
- 事件类型 (什么事件)
- 事件处理程序 (做啥)
<button id="btn">唐伯虎</button> <!-- 事件源:按钮,所以设置id="btn" --> <script> //(1) 事件源 事件被触发的对象 谁 按钮 所以要获取按钮 var btn = document.getElementById('btn');//获得事件源 //(3) 事件处理程序 通过一个函数赋值的方式 完成 btn.onclick = function() {//(2) 事件类型,如何触发什么事件,比如鼠标点击(onclick),还是鼠标经过,还是键盘按下 alert('点秋香');// 点击一个按钮,弹出对话框 } </script>
-
执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
<body> <div>123</div> <script> // 执行事件步骤 // 点击div 控制台输出 我被选中了 // 1. 获取事件源 var div = document.querySelector('div'); // 2.绑定事件 注册事件 // div.onclick // 3.添加事件处理程序 div.onclick = function() { console.log('我被选中了'); } </script> </body>
-
其他鼠标事件
-
-
操作元素(事件方式)
-
改变元素内容
-
element.innerText
:非标准,去除空格和换行,用的少<!-- 写法1:使用事件的方式 --> <div>某个时间</div> <button>显示当前系统时间</button> <script> // 例题:当我们点击了按钮,div里面的文字会发生变化 // 1. 获取元素 var btn = document.querySelector('button');//点按钮 var div = document.querySelector('div');//div要发生变化 // 2.注册事件 btn.onclick = function() { // div.innerText = '2019-6-6';//element.innerText,这个是写死的 div.innerHTML = getDate();//element.innerHTML,写一个getDate函数,直接调用 } function getDate() {//之前写好的函数 var date = new Date(); // 我们写一个 2019年 5月 1日 星期三 var year = date.getFullYear(); var month = date.getMonth() + 1; var dates = date.getDate(); var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; var day = date.getDay(); return '今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]; } </script>
<!-- 写法2:不使用事件的方式 --> <p>1123</p> <script> var p = document.querySelector('p');//获取元素 p.innerHTML = getDate();//修改这个p </script>
-
element.innerHTML
: W3C标准,保留空格和换行的,这个用的更多 -
element.innerText
和element.innerHTML
区别-
前者不识别html标签,后者识别
div.innerText = '<strong>今天是:</strong> 2019';//不识别html所以加粗失败 div.innerHTML = '<strong>今天是:</strong> 2019';//有加粗
-
前者不保留空格和换行,后者保留空格和换行
var p = document.querySelector('p'); console.log(p.innerText);//换行了,空格也没了 console.log(p.innerHTML);//都子啊
-
-
-
改变元素属性,eg. 图片
-
如题是:改变图片的src属性和title属性
<body> <button id="ldh">刘德华</button> <button id="zxy">张学友</button> <br> <img src="images/ldh.jpg" alt="" title="刘德华"> <script> // 修改元素属性 src // 1. 获取元素 var ldh = document.getElementById('ldh'); var zxy = document.getElementById('zxy'); var img = document.querySelector('img'); // 2. 注册事件 处理程序 zxy.onclick = function() { img.src = 'images/zxy.jpg'; img.title = '张学友思密达'; } ldh.onclick = function() { img.src = 'images/ldh.jpg'; img.title = '刘德华'; } </script> </body>
-
案例:分时显示不同图片,显示不同问候语
- 根据系统不同时间来判断,所以需要用到日期内置对象
- 利用多分支语句来设置不同的图片
- 需要一个图片,并且根据时间修改图片,就需要用到操作元素src属性
- 需要一个div元素,显示不同问候语,修改元素内容即可
<body> <!-- 写一个img和div --> <img src="images/s.gif" alt=""> <div>上午好</div> <script> // 1.获取元素 var img = document.querySelector('img'); var div = document.querySelector('div'); // 2. 得到当前的小时数 var date = new Date(); var h = date.getHours(); // 3. 判断小时数改变图片和文字信息 if (h < 12) {//4.分支 img.src = 'images/s.gif'; div.innerHTML = '亲,上午好,好好写代码'; } else if (h < 18) { img.src = 'images/x.gif'; div.innerHTML = '亲,下午好,好好写代码'; } else { img.src = 'images/w.gif'; div.innerHTML = '亲,晚上好,好好写代码'; } </script> </body>
-
-
操作表单元素的属性
-
利用 DOM 可以操作如下表单元素的属性:
type、value、checked、selected、disabled
-
eg. 点击按钮,改变表单值,注:表单里面的值,文字内容是通过 value 来修改的,不能用
.innerHTML
<body> <button>按钮</button> <input type="text" value="输入内容"> <script> // 1. 获取元素 var btn = document.querySelector('button'); var input = document.querySelector('input'); // 2. 注册事件 处理程序 btn.onclick = function() { // input.innerHTML = '点击了'; 这个是普通盒子比如div标签里面的内容,不能用 input.value = '被点击了'; this.disabled = true;//使用disabled禁用,相当于btn.disabled = true; // this 指向的是事件函数的调用者 btn } </script> </body>
-
案例:仿京东显示密码
- 核心思路: 点击眼睛按钮,把密码框类型改为文本框就可以看见里面的密码
- 一个按钮两个状态,点击一次,切换为文本框,继续点击一次切换为密码框
- 算法:利用一个flag变量,来判断flag的值,如果是1 就切换为文本框,flag 设置为0,如果是0 就切换为密码框,flag设置为1(点击多次要变化,引入flag)
<style> .box { position: relative;/* 子绝 */ width: 400px; border-bottom: 1px solid #ccc; /* 只有下边框 */ margin: 100px auto; } .box input { width: 370px; height: 30px; border: 0; /* 没有边框 */ outline: none; } .box img { position: absolute;/* 父相 */ top: 2px; right: 2px; width: 24px; } </style>
<body> <div class="box"><!-- div里面放input和眼睛label --> <!-- Label经常和Input一起使用 --> <label for=""> <img src="images/close.png" alt="" id="eye"> </label> <input type="password" name="" id="pwd"> </div> <script> // 1. 获取元素 var eye = document.getElementById('eye'); var pwd = document.getElementById('pwd'); // 2. 注册事件 处理程序 var flag = 0; eye.onclick = function() { // 点击一次眼睛之后, flag 一定要变化 if (flag == 0) { pwd.type = 'text'; eye.src = 'images/open.png'; flag = 1; // 赋值操作 } else { pwd.type = 'password'; eye.src = 'images/close.png'; flag = 0; } } </script>
-
操作元素样式
-
行内样式:
element.style
,这个权重比较高<body> <div></div> <script> // 1. 获取元素 var div = document.querySelector('div'); // 2. 注册事件 处理程序 div.onclick = function() { // div.style里面的属性 采取驼峰命名法 this.style.backgroundColor = 'purple'; this.style.width = '250px'; } </script> </body>
-
类名样式:
element.className
-
-
案例-样式修改
element.style
:当鼠标点击二维码关闭按钮的时候,则关闭整个二维码-
布局:div里面一个img一个button
-
代码如下
<body> <div class="box"> 淘宝二维码 <img src="images/tao.png" alt=""> <i class="close-btn">×</i> </div> <script> // 1. 获取元素 var btn = document.querySelector('.close-btn'); var box = document.querySelector('.box'); // 2.注册事件 程序处理 btn.onclick = function() { box.style.display = 'none';//只是隐藏起来了,没删掉 //这里不能用this关,因为这里是btn是调用者,要关的不是btn是box } </script> </body>
-
-
案例-样式修改
element.style
:循环精灵图-
每个位置设置好,但是图片不好设置,开始是如下:
-
索引号
i
×44则得到每个精灵图的y坐标 -
CSS代码如下
<style> * { margin: 0; padding: 0; } li { list-style-type: none; } .box { width: 250px; margin: 100px auto; } .box li { float: left; width: 24px; height: 24px; background-color: pink; margin: 15px; background: url(images/sprite.png) no-repeat; } </style>
-
代码如下:
document.querySelectorAll
获得所有的,然后设置Position<body> <div class="box"> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </div> <script> // 1. 获取元素 所有的小li var lis = document.querySelectorAll('li'); for (var i = 0; i < lis.length; i++) { // 让索引号 乘以 44 就是每个li 的背景y坐标 index就是我们的y坐标 var index = i * 44; lis[i].style.backgroundPosition = '0 -' + index + 'px';//0,-44 } </script> </body>
-
-
案例-样式修改
element.style
:显示隐藏文本框内容,光标移入隐藏,移除显示默认值-
获得焦点事件:
onfocus
-
失去焦点事件:
onblur
-
获取元素
var text = document.querySelector('input');
-
注册事件
// 2.注册事件 获得焦点事件 onfocus text.onfocus = function() { console.log('得到了焦点'); } // 3. 注册事件 失去焦点事件 onblur text.onblur = function() { console.log('失去了焦点'); }
-
如果有焦点,文本框里是”手机“(默认信息)则清空,不是”手机“(不为空)则不清空。如果失去焦点,文本框为空,则还原”手机“
-
如果有焦点,文本框字的颜色要变黑
this.style.color
-
代码如下:
<style> input { color: #999; } </style
<body> <input type="text" value="手机"> <script> // 1.获取元素 var text = document.querySelector('input'); // 2.注册事件 获得焦点事件 onfocus text.onfocus = function() { // console.log('得到了焦点'); if (this.value === '手机') { this.value = ''; } // 获得焦点需要把文本框里面的文字颜色变黑 this.style.color = '#333'; } // 3. 注册事件 失去焦点事件 onblur text.onblur = function() { // console.log('失去了焦点'); if (this.value === '') { this.value = '手机'; } // 失去焦点需要把文本框里面的文字颜色变浅色 this.style.color = '#999'; } </script> </body>
-
-
样式较少,可以使用刚刚的
element.style
,但是样式多使用类名样式修改:element.className
-
可以通过修改元素的className更改元素的样式,适合于样式较多或者功能复杂的情况
-
当点击时候,把当前的这个类的名字修改为change这个类名,如下是点击前后的效果以及代码
<body> <div class="first">文本</div> <script> // 1. 使用 element.style 获得修改元素样式 如果样式比较少 或者 功能简单的情况下使用 var test = document.querySelector('div'); test.onclick = function() { this.className = 'change'; } </script> </body>
-
注意:会覆盖原来的类名,如果想要保留原先的类名,我们可以这么做 多类名选择器
<div class="first">文本</div> <script> var test = document.querySelector('div'); test.onclick = function() { this.className = 'first change';//在first的基础上加change } </script>
-
-
案例:用户如果离开密码框,里面输入个数不是6~16,则提示错误信息,否则提示输入正确信息
-
分析
- 首先判断的事件是表单失去焦点 onblur
- 如果输入正确则提示正确的信息颜色为绿色小图标变化
- 如果输入不是6到16位,则提示错误信息颜色为红色 小图标变化
- 因为里面变化样式较多,我们采取className修改样式
-
给定如下html和css
<div class="register"> <input type="password" class="ipt"> <p class="message">请输入6~16位密码</p> </div>
-
获取元素:表单(要是去焦点等),文字(要改变等)
var ipt = document.querySelector('.ipt');//表单 var message = document.querySelector('.message');//信息p
-
注册事件 失去焦点
ipt.onblur = function() { // 根据表单里面值的长度 ipt.value.length if (this.value.length < 6 || this.value.length > 16) { console.log('错误'); }
-
图片要变,文字也变,可以写个css类
.wrong
和.right
,并在原先的message
类上添加。同时使用innerHTML
修改文字.wrong { color: red; background-image: url(images/wrong.png); }
message.className = 'message wrong'; message.innerHTML = '您输入的位数不对要求6~16位';
<script> // 1.获取元素 var ipt = document.querySelector('.ipt');//表单 var message = document.querySelector('.message');//信息p //2. 注册事件 失去焦点 ipt.onblur = function() { // 根据表单里面值的长度 ipt.value.length if (this.value.length < 6 || this.value.length > 16) { // console.log('错误'); message.className = 'message wrong'; message.innerHTML = '您输入的位数不对要求6~16位'; } else { message.className = 'message right'; message.innerHTML = '您输入的正确'; } } </script>
-
-
-
-
操作元素的总结