WebAPI
web APIs是W3C的标准 主要学习DOM BOM
页面交互
API(应用程序编程接口)是一些预先定义的函数,方便用,不需要理解
web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM DOM)
DOM
DOM
(文档对象模型),是W3C组织推荐的处理可扩展标记语言(HTML/XML)的标准编程接口
。
已经定义了有一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式。
DOM树
一个页面就是一个文档 document
页面中的所有标签都是元素 element
网页中所有的内容都是节点 node
DOM把以上内容都看成对象
DOM使得HTML形成一颗DOM树,包含文档、元素、节点
获取元素
DOM主要来操作元素
获取页面中的元素:
-
根据ID获取
getElementById()
var element = document.getElementById(id) // 返回的是一个元素对象
-
根据标签名获取
getElementsByTagName()
var element = document.getElementsByTagName()
返回的是获取元素对象的集合,伪数组形式存储
-
通过HTML5新增的方法
getElementsByClassName()
根据类名获得某些元素集合querySelector()
返回指定选择器的第一个对象 选择器需要加符号(.box #nav)querySelectorAll()
返回指定选择器的所有元素对象 -
特殊元素获取
//1. 获取body元素 var a = document.body; //2. 获取html元素 var b = document.documentElement;
DOM事件
JavaScript可以创建动态页面,事件是可以被JavaScript侦测到的行为
网页中每个元素都可以产生触发JavaScript的事件
事件三要素
事件源
一个对象
var a = document.getElementById('id');
事件类型
如何触发 点击还是经过
事件处理程序
一个函数赋值的方式
// 对象元素+动作函数 = 自定义函数()
a.onclick = function(){
// code
}
DOM事件
事件 | 触发条件 |
---|---|
onload 和 onunload | 用户进入或离开页面时 |
onclick | 鼠标点击 |
onmouseover | 鼠标移动到触发 |
onmouseout | 鼠标离开触发 |
onload
事件可用于检查访客的浏览器类型和版本,以便基于这些信息来加载不同版本的网页。
onload
和 onunload
事件可用于处理 cookies。
节点
节点操作还是为了获取元素
DOM获取元素:
- document.getElementById()
- document.getElementsByTagName()
- document.querySelector
逻辑性不强,繁琐
利用节点层次关系获取元素
- 利用父子兄节点关系获取元素
逻辑性强,简单,兼容性差
什么是节点?
网页中所有的内容都是节点(标签,属性,文本,注释)
在DOM中,节点用node来表示
HTML DOM树中所有节点均可通过JavaScript进行访问,所有HTML元素(节点)均可被修改,创建,删除
一般,节点至少拥有nodeType(节点类型) nodeName(节点名称) nodeValue(节点值)
- 元素节点 nodeType = 1
- 属性节点 nodeType = 2
- 文本节点 nodeType = 3 (文字,空格,换行)
实际开发中,主要还是元素节点(即标签)
节点操作
1)父级节点
子节点.parentNode
- 得到的是离元素最近的父级节点
- 如果找不到,就返回null
2)子节点
父节点.childNodes
- 返回所有的子节点,包括元素和文本
父节点.children
- 只返回子元素节点
父节点.firstChild
- 返回第一个子节点,包含所有节点
父节点.lastChild
- 返回最后一个子节点,同上
父节点.firstElementChild
- 返回第一个子元素节点,last 同理
- 兼容性问题,IE9+支持
3)兄弟节点
节点.nextSibling
…
4)创建节点
document.createElement('tagName')
动态创建
5)删除节点
node.removeChild(child)
阻止链接跳转:<a href='javascript:;'>abc</a>
这个很重要,比如你要做一个按钮,点击后打开或者关闭某个盒子,我们把按钮做成a的样式,是为了鼠标有点击的效果(不然鼠标以为是文字,虽然能点击,但交互性不好)。
设置成a后一定要阻止链接跳转!因为这样才不会刷新,一刷新就又恢复了,就会造成一闪而过的情况。
<a id="log" href="javascript:void(0);">登录</a>
我的总结:
- 链接为真,点击后页面会刷新,跳转到新的页面。
- 链接为假,点击后不刷新,执行我们的 JS 效果。
6)克隆节点
节点.cloneNode()
如果括号参数为空或者false,则是浅拷贝,只克隆节点本身,不克隆里面的子节点。
括号为true,是深拷贝,复制标签+内容
三种动态创建元素区别
document.write()
element.innerHTML
document.createElement()
区别
document.write()
直接将内容写入页面的内容流。当文档流执行完毕,会导致页面全部重绘。
element.innerHTML
将内容写入某个DOM节点,不会导致页面重绘。
document.createElement()
创建多个元素结构清晰。
DOM核心
DOM是属于编程接口,获取过来的DOM元素是一个对象
DOM主要就是对元素的操作:创建
、增删查改
、属性
、事件
创建
- document.write()
- element.innerHTML
- document.createElement()
增
-
appendChild
-
insertBefore
删
- removeChild
改
- 修改元素属性:src href title
- 修改普通元素内容:innerHTML innerText
- 修改表单元素:value type disabled
- 修改元素样式:style className
查
获取查询dom的元素
- DOM的API:getElementById getElementsByTagName
- H5:querySelector querySelectorAll
- 利用节点操作:父子兄
属性操作(主要针对自定义属性)
- setAttribute:设置DOM的属性值
- getAttribute:得到DOM的属性值
- removeAttribute:移出属性值
事件操作(事件源.事件类型 = 函数程序
)
鼠标事件、键盘。。
改变元素内容
获取一个元素的对象,给他一个操作函数,去改变另一个元素的值
innerText
innerHTML
案例:按钮显示当前时间
<body>
<button>显示当前系统时间</button>
<div>某个时间</div>
<script>
// 获取元素
var btn = document.querySelector('button');
var div = document.querySelector('div');
// 注册事件 (元素+操作指令+定义函数)
btn.onclick = function () {
div.innerText = get_the_data();
}
// 获取时间函数
function get_the_data() {
var data = new Date();
var year = data.getFullYear(); //返回年份
var month = data.getMonth() + 1; //返回月份,但是0开头
var dates = data.getDate(); //返回几号
var arr = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
var day = data.getDay(); //周一返回1,周六返回6,周日返回0
return '今天是' + year + '年' + month + '月' + dates + '日' + arr[day];
}
</script>
</body>
案例:切换密码栏输入密码是否可见
<body>
<div class="box">
<input type="password">
</div>
<button>code</button>
<script>
var btn = document.querySelector('button');
var pwd = document.querySelector('input')
var flag = 0;
btn.onclick = function(){
if (flag == 0){
pwd.type = 'text';
flag = 1;
}
else{
pwd.type = 'password';
flag = 0;
}
}
</script>
</body>
操作元素总结
操作元素
-
操作元素内容
innerText
innerHTML
-
操作元素属性
src
href
title
alt
-
操作表单元素属性
type
value
disabled
(普通盒子里面的文字是用innerHTML来修改,表单里面的文字用value来改)
-
操作元素样式属性
element.style
(少)className
(多)
案例:换背景壁纸
四个图片小图排成一起,每点击一张图片,就把body的背景图片换成这张壁纸
<style>
body {
background: url("/img/bc1.jpg") no-repeat center top;
}
</style>
<body>
<ul class="baidu">
<li><img src="/img/bc1.jpg" alt=""></li>
<li><img src="/img/bc2.jpg" alt=""></li>
<li><img src="/img/bc3.jpg" alt=""></li>
<li><img src="/img/bc4.jpg" alt=""></li>
</ul>
<script>
// 获取元素 取出ul img里面的所有图片
var imgs = document.querySelector('.baidu').querySelectorAll('img');
// 遍历所有图片,添加点击事件,把当前(this)的图片地址加到body里面
for (var i=0; i<imgs.length; i++){
imgs[i].onclick = function(){
// this.src就是我们点击图片的路径
document.body.style.backgroundImage = 'url('+this.src+')';
}
}
</script>
</body>
案例:列表的全选与反全选
// jall是表头复选框input的id
// jtb是表身的id
var jall = document.getElementById('jall'); //上面的全选按钮
var jtb = document.getElementById('jtb').getElementsByTagName('input'); //下面的所有的复选框
jall.onclick = function(){
for(var i=0; i<jtb.length; i++){
jtb[i].checked = this.checked;
}
}
for(var i=0; i<jtb.length; i++){
jtb[i].onclick = function(){
var flag = true;
for(var i=0; i<jtb.length; i++){
if(!jtb[i].checked){
flag = false;
}
}
jall.checked = flag;
}
}
监听事件(注册&解绑)
addEventListener() 方法
添加当用户点击按钮时触发的事件监听器:
document.getElementById("myBtn").addEventListener("click", displayDate);
addEventListener() 方法为指定元素指定事件处理程序。
addEventListener() 方法为元素附加事件处理程序而不会覆盖已有的事件处理程序。
能够向一个元素添加多个事件处理程序。
能够向一个元素添加多个相同类型的事件处理程序,例如两个 “click” 事件。
能够向任何 DOM 对象添加事件处理程序而非仅仅 HTML 元素,例如 window 对象。
addEventListener() 方法使我们更容易控制事件如何对冒泡作出反应。
当使用 addEventListener() 方法时,JavaScript 与 HTML 标记是分隔的,已达到更佳的可读性;即使在不控制 HTML 标记时也允许您添加事件监听器。
能够通过使用 removeEventListener() 方法轻松地删除事件监听器。
举例:此示例使用 addEventListener() 方法将 click 事件(显示当前时间)附加到按钮。
<button id="myBtn">试一试</button>
<p id="demo"></p>
<script>
document.getElementById("myBtn").addEventListener("click", displayDate);
function displayDate() {
document.getElementById("demo").innerHTML = Date();
}
</script>
注意,这里不能使用匿名函数的方式,要把函数名明确的显示出来,方便调用。调用的时候不用加引号。
但是要用也是可以的,比如
element.addEventListener("click", function(){ alert("Hello World!"); });
语法
element.addEventListener(event, function, useCapture);
- 第一个参数是事件的类型(比如 “click” 或 “mousedown”)。
- 第二个参数是当事件发生时我们需要调用的函数。
- 第三个参数是布尔值,指定使用
事件冒泡(false)
还是事件捕获(true)
。此参数是可选的。
注意: 请勿对事件使用 “on” 前缀;请使用 “click” 代替 “onclick”。
DOM事件流
事件流描述的是从页面中接受事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
三个阶段
捕获阶段 从上往下 顶层到底层
当前目标阶段
冒泡阶段 从下往上 底层到顶层
JS只能得到其中一个阶段,通过设定布尔值,让父子关系的盒子事件有一个先后顺序。
实际开发中更关注事件冒泡
有些事件是没有冒泡的:onblur onfocus
事件对象
什么是事件对象?
var j = document.querySelector('div');
j.onclick = function(event){};
event就是一个事件对象,写到监听函数小括号里面
onclick
是事件(鼠标事件、键盘事件),event
是事件对象
事件对象是事件的一系列相关数据的集合
查看事件对象
j.addEventListener('click', function(e){
console.log(e);
})
e里面就包含了鼠标点击的一系列信息
兼容性问题:
IE 678 通过window.event获取
console.log(window.event)
兼容写法:e = e ||window.event
事件对象的常用属性和方法
事件对象属性方法 | 说明 | 兼容问题 |
---|---|---|
e.target | 返回触发事件的对象 | 标准 |
e.srcElement | 返回触发事件的对象 | 非标准 ie6-8使用 |
e.type | 返回事件的类型,比如click mouseover | 不带on |
e.cancelBubble | 改属性阻止冒泡 | 非标准 ie6-8使用 |
e.returnValue | 该属性阻止默认事件,比如不让链接跳转 | 非标准 ie6-8使用 |
e.preventDefault() | 该方法阻止默认事件,比如不让链接跳转 | 标准 |
e.stopPropagation() | 该方法阻止冒泡 | 标准 |
this 和 target
- 给谁绑定事件,this就指向谁
- 我们点击哪个对象,(这个元素没有绑定事件,但是可以冒泡排上去),指向的就是这个对象元素
阻止冒泡
冒泡有好处,也有坏处
div.addEventListener('click', function(e){
...
e.stopPropagation();
}, false);
事件委托
也称事件代理,在jQ中称为事件委派
事件委托的原理:
不是每个子节点单独设置事件监听器,而是监听器设置在父节点上,然后利用冒泡原理影响每个子节点。
作用是 只操作一次DOM,提高性能
我们在父节点上注册事件,但我们点击的是自节点。我们想改变点击的子节点的样式,可以用event.target来做
禁用选项
禁用右键菜单
document.addEventListener('contextmenu', function(e){
e.preventDefault();
})
禁用鼠标选中文字
document.addEventListener('selectstart', function(e){
e.preventDefault();
})
鼠标事件对象
键盘事件对象
获得焦点
focus()
案例:按下s键,搜索框获得焦点
<body>
<input type='text'>
<script>
var search = document.querySelector('input');
document.addEventListener('keyup', function(){
if(e.keyCode === 83){
search.focus();
}
})
</script>
</body>
注意keyup keydown的区别
NOTE:keydown和keypress在文本框里面的特点:他们两个ssh事件触发的时候,文字还没有落入文本框中。keyup触发时文字已经进去了
H5自定义属性
保存并使用数据,数据保存到页面中而不是数据库中
通过 getAttribute('属性')
获取
H5规范:data- 开头
H5新增:element.dataset.index ie11才支持
表单验证
🐌数据验证
典型的数据验证有:
- 必需字段是否有输入?
- 用户是否输入了合法的数据?
- 在数字字段是否输入了文本?
大多数情况下,数据验证用于确保用户正确输入数据。
数据验证可以使用不同方法来定义,并通过多种方式来调用。
服务端数据验证是在数据提交到服务器上后再验证。
客户端数据验证是在数据发送到服务器前,在浏览器上完成验证。
用DOM获取到节点元素,加.value
拿到元素的值
1️⃣ 判断表单字段(fname)值是否存在,弹出警示框
写一个全局JavaScript函数来做验证,这个函数获取到HTML里面表单的值,做一个判断。在表单的onsubmit确定返回这个函数,就使用到了JS的表单验证
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function validateForm() {
// 表单里面的文字输入框里的值
var x = document.forms["myForm"]["fname"].value;
if (x == null || x == "") {
alert("需要输入名字。");
return false;
}
}
</script>
</head>
<body>
<form name="myForm" action="demo_form.php" onsubmit="return validateForm()" method="post">
名字: <input type="text" name="fname">
<input type="submit" value="提交">
</form>
</body>
</html>
2️⃣ 验证输入的数字是否符合要求,绑定点击事件
写在body里面的JavaScript函数,用来操控DOM元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>请输入 1 到 10 之间的数字:</p>
<input id="numb">
<!--按钮绑定点击事件函数,函数判断输入框里的值的范围-->
<button type="button" onclick="myFunction()">提交</button>
<p id="demo"></p>
<script>
function myFunction() {
var x, text;
// 获取 id="numb" input框里的值
x = document.getElementById("numb").value;
// 如果输入的值 x 不是数字或者小于 1 或者大于 10,则提示错误
if (isNaN(x) || x < 1 || x > 10) {
text = "输入错误";
} else {
text = "输入正确";
}
document.getElementById("demo").innerHTML = text;
}
</script>
</body>
</html>
表单自动验证,不需要写函数
我们使用 required
属性阻止表单提交
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form action="demo_form.php" method="post">
<input type="text" name="fname" required="required">
<input type="submit" value="提交">
</form>
<p>点击提交按钮,如果输入框是空的,浏览器会提示错误信息。</p>
</body>
</html>
空提交,会输出提示信息,“请填写次字段”
IE9-
不支持
约束验证
H5新增了 约束验证,基于如下:
- HTML 输入属性
- CSS 伪类选择器
- DOM 属性和方法
约束验证 HTML 输入属性(这些都是写在input里面)
属性 | 描述 |
---|---|
disabled | 规定输入的元素不可用 |
max | 规定输入元素的最大值 |
min | 规定输入元素的最小值 |
pattern | 规定输入元素值的模式 |
required | 规定输入元素字段是必需的 |
type | 规定输入元素的类型 |
约束验证 CSS 伪类选择器(写在CSS里面)
选择器 | 描述 |
---|---|
:disabled | 选取属性为 “disabled” 属性的 input 元素 |
:invalid | 选取无效的 input 元素 |
:optional | 选择没有"required"属性的 input 元素 |
:required | 选择有"required"属性的 input 元素 |
:valid | 选取有效值的 input 元素 |
checkValidity() 和 setCustomValidity()
Property | Description |
---|---|
checkValidity() | 如果 input 元素中的数据是合法的返回 true,否则返回 false。 |
setCustomValidity() | 设置 input 元素的 validationMessage 属性,用于自定义错误提示信息的方法。 |
简单的说,checkValidity()
判断数据是不是合理的,setCustomValidity()
自定义报错的提示信息
BOM
浏览器对象模型
与浏览器窗口交互
核心对象是window
BOM比DOM更大,包含DOM
window
document
location
navigation
screen
history
window对象的常见事件
页面加载事件
window.addEventListener(‘load’, function(){ })
load等页面内容全部加载完毕,包含页面DOM元素,图片,css等等
document.addEventListener(‘DOMContentLoaded’, function(){ })
DOMContentLoaded是DOM加载完毕,比load快
窗口事件
window.resize 窗口大小发生像素级变化,就触发事件
响应式布局
window.innerWidth 当前屏幕的宽度
定时器
setTimeout()
window.setTimeout(调用函数, [延迟的毫秒数]);
时间到后执行,只用一次
最好给定时器赋值一个标识符
停止计时器
window.clearTimeout(timeoutID)
setInterval()
window.setInterval(回调函数, [间隔的毫秒数])
每隔多少秒就执行一次,一直持续下去
案例:JS原生倒计时
// 获取元素
var hour = document.querySelector('.hour');
var min = document.querySelector('.min');
var sec = document.querySelector('.sec');
// 当前时间
var inputTime = +new Date('2020-8-6 00:00:00');
// 先用一次倒计时,再定时
countDown();
// 开启定时器
setInterval(countDown, 1000);
// 写倒计时函数
function countDown() {
var nowTime = +new Date();
var times = (inputTime - nowTime) / 1000;
var h = parseInt(times / 60 / 60 % 24);
h = h < 10 ? '0' + h : h;
hour.innerHTML = h;
var m = parseInt(times / 60 % 60);
m = m < 10 ? '0' + m : m;
min.innerHTML = m;
var s = parseInt(times % 60);
s = s < 10 ? '0' + s : s;
sec.innerHTML = s;
}
小注意:null 是一个空对象
JS考点之一:this指向问题
一般情况下,this指向的是调用它的对象
1.全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)
2.方法调用中谁调用this指向谁
3.构造函数中this指向构造函数的实例
JS执行队列
JavaScript语言的特点就是单线程
,一个时间内只能做一件事
同步和异步
-
同步任务
同步任务都在主线程上执行,形成一个
执行栈
。 -
异步任务
回调函数实现
任务队列
异步任务有以下三种类型
事件 例子 普通事件 click resize 资源加载 load error 定时器 setInterval setTimeout
location对象
location属性用于获取和设置窗体的URL,可以解析URL
统一资源定位符
URL的一般格式为:
protocol://host[:port]/path/[?query]#fragment
组成 | 说明 |
---|---|
protocol | 通信协议 |
host | 域名 |
port | 端口 |
path | 资源路径 |
query | 提供给网络服务器的额外参数 |
fragment | 锚点 |
location对象的属性
location对象属性 | 返回值 |
---|---|
location.href | 获取或者设置整个URL |
location.host | 返回主机(域名) |
location.port | 返回端口号 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段 |
location对象的方法
location对象方法 | 返回值 |
---|---|
location.assign() | 跳转页面,记录历史,可回退 |
location.replace() | 替换当前页面,不记录历史 |
location.reload() | 刷新 |
字符串操作
- 截取字符串
substr('起始的位置', 截取几个字符)
比如,对 str = “abcd”
var new = str.substr(1)
new就是bcd
-
字符串分割为数组
split( ‘中间隔的符号’ )
navigator对象
浏览器的信息
userAgent 返回客户机使用的浏览器类型 PC 或 移动端
history对象
历史记录
该对象包含了用户在浏览器窗口中访问过的URL