是W3C的标准,主要学习页面交互功能实现交互效果;
API是一些预先定义的函数,简单理解就是给程序员提供的一种工具,以便能轻松的实现想要完成的功能;
Web APIs是浏览器的API;
DOM
文档对象模型,是处理html或者xml的编程接口;可以通过里面的接口修改网页内容,样式,结构;
- 文档:一个文档就是一个页面,DOM中使用document表示;
- 元素:页面中所有的标签就是元素;
- 节点:网页中所有的内容都是节点,比如标签,内容,文本,注释等。
获取元素
- 根据id获取:
使用getElementByld()获取,因为文档页面从上往下加载,所以要先有标签 所以我们script写在标签下面;
var timer =document.getElementById('time');
console.log(timer);
console.log(typeof timer);//这里返回值是对象object
console.dir(timer)//它是用来打印我们返回的元素对象,更好地查看里面的属性和方法;
-
根据标签名获取:
使用getElementByTagName()方法可以获取指定标签名的对象的集合;
返回对象是获取过来的元素对象的集合,以伪数组的形式存储的;
如果页面中没有元素,返回的是空的伪数组; -
通过HTML5新增方法获取:
(1) getElementsByClassName(‘这里面填class的名字’);根据类名返回元素集合;
(2)querySelector(‘.box’/‘#nav’/‘li’):只能返回指定选择器的第一个元素对象;这里切记里面的选择器前面需要加符号;
(3)querySelectorAll():返回的是指定选择器的所有元素对象集合,还是伪数组的形式;这里也要注意选择器前面需要加符号; -
特殊元素获取:
(1)获取body元素: var bodyEle = document.body;
(2)获取html元素: document.documentElement;
事件基础
- 就是js里面的触发机制;
事件由三部分组成:事件源,事件类型和事件处理程序;
事件源:事件被触发的对象;
事件类型:如何触发;
事件处理程序:通过函数赋值的方式触发;
<body>
<button id="btn">syc</button>
<script>
var btn = document.getElementById('btn');
btn.onclick= function (){
alert('超棒!');
}
</script>
- 执行事件的步骤:
获得事件源----注册事件(绑定事件)----添加事件处理程序(采取函数赋值形式)
<body>
<div>123</div>
<script>
//1 获取事件源
var div =document.querySelector('div');
//2-绑定事件
div.onclick;
//3-添加事件处理程序
div.onclick=function (){
alert('我被选中了')
}
</script>
</body>
操作元素(核心)
改变元素内容
- element.innerText;不识别html标签;非标准
- element. innerHtml;识别html标签;W3C标准;保留空格和换行;
常用元素的属性操作
<body>
<button id="ldh">刘德华</button>
<button id="zxy">张学友</button>
<img src="images/ldh.jpeg" alt="">
<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.jpeg';
}
</script>
</body>
表单元素的属性操作
type,value,checked,selected,disable;
下面展示的是value属性和disabled的用法:
<body>
<button>点这里</button>
<input type="text" value="输入内容">
<script>
var btn = document.querySelector('button');
var input = document.querySelector('input');
btn.onclick =function(){
input.value='被点击啦';
//想要某个表单被禁用 不能再点击 用disabled
btn.disabled=true;
//和下面这种结果是一样的:
this.disabled=true;
//this指向的是这个函数的调用者 在这里就是btn;
}
</script>
</body>
样式属性操作
- element.style :行内样式操作;
- element.className:类名样式操作;
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
width: 300px;
height: 300px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
var div=document.querySelector('div');
div.onclick=function (){
//div里面的属性采取驼峰命名法
div.style.backgroundColor='purple';
div.style.width='400px';
}
</script>
</body>
淘宝二维码关闭案例
display.none;隐藏
display.block;显示
显示隐藏文本内容
首先表单需要两个事件:
获得焦点onfocus
失去焦点 onblur
节点操作
BOM
操作元素
样式操作
之前讲到,如果样式比较少,或者功能比较简单用element.style修改外观样式:
- 获取元素:var xxx= document.queryselector();
- 触发动作:这里有很多触发动作的比如onclick(),注意后面要用function实现;
类名样式操作
this.className = ’ 类名 ’
var ipt =document.querySelector('.ipt')
var message = document.querySelector('.message')
ipt.onblur= function (){
if(ipt.value.length<6||ipt.value.length>16){
console.log('wrong');
message.className='wrong'
message.innerHTML='位数不对';
}
}
排他思想
就是用到了双层循环;首先先排除所有人,然后再设置自己的样式;
<script>
//获取所有按钮
var btns = document.querySelectorAll('button');
//btn得到的是伪数组,这里遍历每一个button
for (var i=0;i<btns.length;i++){
btns[i].onclick=function (){
//2。所以可以在这里先让所有的背景颜色清空
for (i=0;i<btns.length;i++){
btns[i].style.backgroundColor='';
}
this.style.backgroundColor='pink';//1。但是这里循环内部累计了,都变粉色了
}
}
</script>
获得/设置/移除属性
- getAttribute(属性);是主要获得自定义的属性;
- element.属性;获得内置属性值(元素本身自带的属性);
设置:
- element.属性=值
- setAttribute(属性,值)
移除
1 . remove
节点操作
获取节点
.parentNode------------------得到父节点;但这个得到的是离他最近的父节点;如果找不到父节点就返回为空null;
console.log(erweima.parentNode);//这个就是erweima的父节点
.childNode--------------------得到子节点;
.children-----------------------也是得到子节点,是实际开发常用的;
DOM 提供的方法(API)获取
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等
console.log(ul.childNodes);
console.log(ul.childNodes[0].nodeType);
console.log(ul.childNodes[1].nodeType);
children 获取所有的子元素节点 也是我们实际开发常用的
console.log(ul.children);
firstChild/lastChild----------------第一个/最后一个子节点,不管是文本节点还是元素节点;
firstElementChild/lastElementChild----------------第一个/最后一个子元素节点;
返回第一个子元素节点 ie9才支持
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
实际开发的写法 既没有兼容性问题又返回第一个子元素,就是用刚才那种返回子元素的方法,后面加上数组下标:
console.log(ol.children[0]);
console.log(ol.children[ol.children.length - 1]);
创建节点
分为两步: 1. 创建元素 2. 添加元素
.createElement-----------------------------创建;
node.appendChild(child)-----------------添加,类似数组里面的push;
node.insertBefore(child, 指定元素)------添加到指定元素的前面;
// 1. 创建节点元素节点
var li = document.createElement('li');
// 2. 添加节点 node.appendChild(child) node 父级 child 是子级 后面追加元素 类似于数组中的push
var ul = document.querySelector('ul');
ul.appendChild(li);
// 3. 添加节点 node.insertBefore(child, 指定元素);
var lili = document.createElement('li');
ul.insertBefore(lili, ul.children[0]);
// 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
删除节点
node.removeChild(child)--------------------------删除元素
复制节点
- 复制:xxx.node.Clone();()为空或为false的话只复制标签,不复制里面的内容;xxx.node.Clone(true)的话是复制里面的内容;
- 然后用appendChild添加进去就行了;
3种动态创建元素
- document.write 直接写入内容流,但是文档流执行完毕会导致页面重绘;
- inner.HTML 将内容写入某个DOM节点,不会导致页面冲绘;
创建多个元素效率高,不要采用拼接字符串,采用数组形式拼接,结构稍微复杂; - createElenemt(),创建多个元素效率稍微低一点,但是结构清晰;
操作元素总结
操作元素内容:innerText;innerHTML;
操作元素常见属性:src href title alt
操作表单元素属性:type,value,disabled
操作元素常见样式:元素少用element.style;元素多用className;
事件
注册事件
-
传统方式:比如onclick
-
方法监听注册方式:
addEventListener事件监听方式
(1) 里面的事件类型是字符串 必定加引号 而且不带on
(2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function() {
alert(22);
})
btns[1].addEventListener('click', function() {
alert(33);
})
删除事件
- 传统方式删除事件:在注册事件的function下面写上=null;
divs[0].onclick = null;
- removeEventListener 删除事件
divs[1].addEventListener('click', fn)//这里先写移除函数,不需要调用➕小括号
function fn() {//这里定义fn这个函数
alert(22);
divs[1].removeEventListener('click', fn);
}
- detachEvent删除事件;
divs[2].attachEvent('onclick', fn1);
function fn1() {
alert(33);
divs[2].detachEvent('onclick', fn1);
}
DOM事件流
事件流描述的是从页面中接收事件的顺序,分为三个阶段:
- 捕获阶段:如果addEventListener 第三个参数是 true 那么则处于捕获阶段
- 当前目标阶段
- 冒泡阶段:如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段 son -> father ->body -> html -> document
事件对象
- event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看
- 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
- 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键
- 这个事件对象我们可以自己命名 比如 event 、 evt、 e
- 事件对象也有兼容性问题 ie678 通过 window.event 兼容性的写法 e = e || window.event;
事件对象常见属性和方法:
常见事件对象的属性和方法:
1. e.target 返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素)
区别 : e.target 点击了那个元素,就返回那个元素 ;this 那个元素绑定了这个点击事件,那么就返回谁
2. e.preventDefault() 阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交;return false也可以,但是只要有return的话后面的代码就不执行了;
3. 怎么阻止冒泡:
标准写法:e,stopPropagation(),stop 停止 ,Propagation 传播;
e.cancelBubble = true;
事件委托
鼠标事件
我是一段不愿意分享的文字
<script>
//禁止鼠标右键菜单contextmenu
document.addEventListener('contextmenu',function (e) {
e.preventDefault();
})
//禁止鼠标选中文字
document.addEventListener('selectstart',function (e) {
e.preventDefault();
})
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function(e) {
// 1. client 鼠标在可视区的x和y坐标,就是当前的可视界面的位置
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------------');
// 2. page 鼠标在页面文档的x和y坐标,就是相对于一整个页面从头开始的坐标
console.log(e.pageX);
console.log(e.pageY);
console.log('---------------------');
// 3. screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
mouseenter和mouseover的区别
mouseenter只经过自身盒子触发;
mouseover经过自身盒子和经过子盒子都触发;
常用键盘事件
- keyup 按键弹起的时候触发
// document.onkeyup = function() {
// console.log('我弹起了');
// }
document.addEventListener('keyup', function() {
console.log('我弹起了');
})
- keydown 按键按下的时候触发 能识别功能键 比如 ctrl shift 左右箭头啊
document.addEventListener('keydown', function() {
console.log('我按下了down');
})
- keypress 按键按下的时候触发 不能识别功能键 比如 ctrl shift 左右箭头啊
document.addEventListener('keypress', function() {
console.log('我按下了press');
})
三个事件的执行顺序 keydown – keypress – keyup
键盘事件对象
- keyCode(添加侦听器)
其中keyup和keydown不区分字母大小写,keypress区分字母大小写;实际开发里面常用keyup和keydown;
document.addEventListener('keyup',function (e) {
console.log(e.keyCode)
})
案例:京东快递单号查询
<div class="search">
<!-- 字号偏大的一个盒子-->
<div class="con">123</div>
<!-- 下面的一个输入盒子-->
<input type="text" placeholder="请输入您的快递单号" class="jd">
</div>
<script>
var con = document.querySelector('.con')
var jd_input = document.querySelector('.jd')
jd_input.addEventListener('keyup',function () {
if (this.value==''){
con.style.display='none'
}else {
con.style.display = 'block';
con.innerText = this.value;
}
})
这个案例里面就必须要用keyup,因为字还没按进去的时候,就触发了事件,触发事件的时候value为空,为空时display还是none,取不过来;
BOM浏览器对象模型
BOM–浏览时对象模型;给浏览器窗口做交互效果;比DOM大,document就是window对象的一部分;
window对象常见的事件
加载
window.onload-------页面加载事件:就是在页面中所有元素和事件都加载完成之后再开始执行这个事件;这样就可以把js的代码写在页面元素的任何地方;但这种注册事件方式只能写一个,如果有多个就只执行最后那个,所以我们平时生产环境里面会用到另一种实现方式:window.addEventListener('load',function(){})
DOMContentLoaded-------窗口加载事件,仅当DOM加载完成事件就触发;不包括要再去加载样式表,图片,flash等;就是只要各种标签加载完就可以了;这个更快一点;
window.addEventListener('DOMContentLoaded',function(){})
窗口大小
window.onresize-----只要窗口大小发生变化就会触发这个事件;
window.innerWidth是当前屏幕宽度
window.addEventListener('resize',function(){})
定时器
- setTimeout(调用函数-字符串形式,[延迟的秒数])---------用于设置一个定时器,该定时器在定时器到期后执行调用函数,这里这个调用函数就是回调函数;
1.
setTimeout(function() {
console.log('时间到了');
}, 2000);
2.
function callback() {
console.log('爆炸了');
}
var timer1 = setTimeout(callback, 3000);
模拟五秒钟关闭广告:
<img src="images/ad.jpg" alt="" class="ad">
<script>
var ad = document.querySelector('.ad');
setTimeout(function () {
ad.style.display='none';
},5000)
</script>
- 停止定时器:clearTimeout(定时器名字)
<img src="images/ad.jpg" alt="" class="ad">
<button>不管广告啦</button>
<script>
var ad = document.querySelector('.ad');
var btn = document.querySelector('button')
var Timer=setTimeout(function () {
ad.style.display='none';
},5000)
btn.addEventListener('click',function () {
clearTimeout(Timer);
})
</script>
- setInterval()计时器;这个是每隔所定的时间,就调用一次function;
<script>
var Timer = setInterval(function () {
console.log('syc超棒')
},1000);
</script>
- 这个也有停止计时效果:clearInterval(定时器名字);
tihs指向问题
在全局作用下的函数都是window的方法,一般情况下this指向的都是window;
谁调用的函数,this指向的就是哪个对象;
js执行机制
- 先执行主线程执行栈,在执行放入任务队列中的异步任务 ;(主线程就是同步任务,任务队列是异步任务);
location对象
- location.assign():页面跳转
- location.replace():页面跳转但是不能回退,由于不记录浏览历史
- location.reload():加载刷新的意思,不加参数就是刷新,加参数true就是强制刷新;
navigator对象
history对象
history.forward():前进
history.back():后退
history.go():前进x步,这个x就是()里面的参数,写几就是几,甚至可以是-1;
pc端网页特效
元素偏移量 offset系列
- 可以获取元素距离父元素的位置(带有定位,如果没有带有定位的话就以body为准);
console.log(father.offsetTop);
console.log(father.offsetLeft);
- 可以返回当前元素的偏移位置,大小;包含padding + border + width
console.log(w.offsetWidth);
console.log(w.offsetHeight);
- 返回带有定位的父亲 否则返回的是body;
console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body
console.log(son.parentNode); // 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
- 和style的区别:就是去获取位置什么的时候,可以用offset,但是offset是只读属性,style是可读写属性,是可以进行赋值改变的;
元素可视区client系列
立即执行函数:不用进行调用直接执行;
两种写法:(function() {})();或者(function(){}());
dpr 物理像素比
元素滚动scroll系列
(仿淘宝页面滚动案例)
获得的是元素真正的,元素内容大小;
scroll就是被卷进去的长度
- scroll滚动事件:当我们滚动条发生变化的时候会触发的事件;
- pageYoffset 页面被卷进去的部分
三大系列总结
它们擅长的用法:
- offset系列:经常用于获取元素位置: offsetLeft,offsetTop;
- client系列:经常用于获取元素大小:clientWidth,clientHeight;
- scroll系列:经常用于获取滚动距离:scrollTop,scrollLeft;
- 注意页面滚动的距离通过window.pageXOffset实现的;
动画原理
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意:动画效果必须要加定位;
var div = document.querySelector('div');
var timer = setInterval(function() {
if (div.offsetLeft >= 400) {
// 停止动画 本质是停止定时器
clearInterval(timer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 30);
给不同的元素添加不同的定时器
- obj.timer;
- 一个bug:不断点击定时器就开启了很多个定时器,速度就会越来越快
解决方案就是:让我们的元素只有一个定时器执行
先清除以前的定时器,只保留当前的一个定时器执行:
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if (obj.offsetLeft >= target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
缓慢动画
缓动动画函数封装obj目标对象 target 目标位置
思路:
1. 让盒子每次移动的距离慢慢变小, 速度就会慢慢落下来。
2. 核心算法:(目标值 - 现在的位置) / 10 做为每次移动的距离 步长
(有步长还能让步长成为负数,往后退)
var step = (target - obj.offsetLeft) / 10;
- 停止的条件是: 让当前盒子位置等于目标位置就停止定时器