一、Web APIs简介
1.Web APIs 和 JS 基础关联性
2.API 和 Web API
二、DOM
1.DOM简介
2.获取元素
3.事件基础
4.操作元素
5.节点操作
<ol>
<li></li>
<li></li>
<li></li>
</ol>
<script>
var ol = document.quertSelector('ol')
console.log(ol.children[0])
console.log(ol.children[ol.children.length - 1])
</script>
//动态生成表格
<body>
<table cellspacing='0' border="1" bordercolor="black">
<thead>
<tr>
<td>作者姓名</td>
<td>书名</td>
<td>价格</td>
<td>操作</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1.准备好学习数据
var dates = [{
name: '周蕴贤',
subject: 'JavaScript',
score: 100
}, {
name: '张大斌',
subject: 'JavaScript',
score: 99
}, {
name: '周小贤',
subject: 'JavaScript',
score: 90
}, {
name: '周大贤',
subject: 'JavaScript',
score: 80
}];
// 2. 往tbody 里面创建行,
var tbody = document.querySelector('tbody')
for (var i = 0; i < dates.length; i++) { //遍历行
//创建行
var tr = document.createElement('tr');
tbody.appendChild(tr);
// 行里面创建单元格 td 单元格的数量1取决于每个对象里面的属性个数 for 循环遍历对象
for (var k in dates[i]) {
// 创建单元格
var td = document.createElement('td')
td.innerHTML = dates[i][k];
// console.log(dates[i][k]);
//把对象里面的属性值 给td
tr.appendChild(td)
}
// 3. 创建有删除 两个字的单元格
var td = document.createElement('td')
td.innerHTML = '<a href="#">删除</a>'
tr.appendChild(td)
}
// 4 删除操作
var as = document.querySelectorAll('a')
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
// 删除当前 行 tr
tbody.removeChild(this.parentNode.parentNode)
}
}
</script>
6.DOM重点核心
三、事件高级
1.注册事件(绑定事件)
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<button>ie9 attachEvent</button>
<script>
var btns = document.querySelectorAll('button')
// 1. 传统方法方式注册事件
btns[0].onclick = function () { //要加on哦
alert('hi')
}
btns[0].onclick = function () { //这里会覆盖前面的同类型事件
alert('你好')
}
btns[0].onmouseleave = function () { //有效,不同类型
alert('离开')
}
// 2. 事件监听注册事件
// (1)里面的事件类型是字符串 必定加引号 而且不带on
// (2) 同一个元素 ,同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click',()=>alert(22) );
btns[1].addEventListener('click',function() {
alert(33)
})
btns[1].addEventListener('mouseleave',function() {
alert(44)
})
btns[2].attachEvent('onclick',function(){
alert('11')
})
</script>
2.删除事件(解绑事件)
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var div = document.querySelectorAll('div')
div[0].onclick = function () {
alert(1)
// 传统方式删除事件
div[0].onclick = null;
}
div[1].addEventListener('click',fn) // 里面fn 不需要调用加小括号
function fn () {
alert(22)
div[1].removeEventListener('click',fn)
}
// 3.
div[2].attachEvent('onclick',fn1)
function fn1 () {
alert(33)
div[2].detachEvent('onclick'.fn1)
}
</script>
</body
3.DOM事件流
<style>
.father {
width: 100px;
height:100px;
background-color: pink;
overflow: hidden;
}
.father .son {
width: 50px;
height: 50px;
background-color: purple;
text-align: center;
margin: 25px auto;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
// dom 事件流 三个阶段
// 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段
// 2. onclick 和 attachEvent (ie) 只能得到冒泡阶段
// 3. 捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段 document -> html -> body
// -> father -> son
var son = document.querySelector('.son')
// son.addEventListener('click',function(){
// alert('son')
// },true)
var father = document.querySelector('.father')
// father.addEventListener('click',function(){
// alert('father')
// },true)
// 4. 冒泡阶段 如果addEventListener 第三个参数是 fales 或者 省略 那么则处于捕获阶段 son -> father -> body
//-> html -<document
son.addEventListener('click',function(){
alert('son')
})
father.addEventListener('click',function(){
alert('father')
})
document.addEventListener('click',function() {
alert('document')
})
</script>
4.事件对象
<body>
<div>123</div>
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
<script>
// 常见事件对象的属性和方法
// 1. e.target 返回的是触发事件对象 (元素) this 返回的是绑定事件对象 (元素)
// 区别 :e.targer 点击了那个元素,就返回那个元素 ,this 那个元素绑定了这个点击事件,那么就返回谁
var div = document.querySelector('div');
div.addEventListener('click', function (e) {
console.log(e.target);
console.log(this);
})
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
// 我们给ul 绑定了事件 那么this 就指向 ul
console.log(this);
console.log(e.currentTarget);
// e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是 li e.target 指向的就是li
console.log(e.target);
})
// 了解兼容性
// div.click = function (e) {
// e = e || window.event;
// var target = e.target || e.srcElement;
// console.log(target);
// }
</script>
</body>
5.阻止事件冒泡
6.事件委托(代理、委派)
7.常用的鼠标事件
重点注意还有mouseenter和mouseleave这两个不会冒泡 笔记在后面元素滚动scroll
8.常用的键盘事件
四、BOM浏览器对象模型
1.BOM概述
2.window对象的常见事件
3.定时器
4.JS执行机制
5.location对象
//路径传参
<body>
<div>
</div>
<script>
console.log(location.search); //?uname=asd
// 1.先去掉? substr('起始位置',截取几个字符)
var params = location.search.substr(1);
// console.log(params);
// 2. 利用等号把字符串分割成数组
var arr = params.split('=')
// console.log(arr);
var div = document.querySelector('div')
div.innerHTML = arr[1]+ '欢迎你';
</script>
</body>
//
<body>
<form action="index.html">
用户名: <input type="text" name="uname">
<input type="submit" value="登录">
</form>
<script>
</script>
</body>
6.navigator对象
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
window.location.href = ""; //手机
} else {
window.location.href = ""; //电脑
}
7.history对象
8.本地存储
会话存储的数据只能在同一个窗口中共享,其他窗口是获取不到数据的
本地储存是多个窗口共享
两种存储都是在同源策略下才能共享的
五、PC端网页特效
1.元素偏移量offset系列
案例:京东放大镜和可拖动模态框
2.元素可视区client系列
2.函数自调用
<body>
<script>
// 1. 立即执行函数: 不要调用,立马能够自己执行的函数
// function fn () {
// console.log(1);
// }
// fn()
// 2. 写法
// (function(){})() 或者 (function(){}())
(function(a,b) {
console.log(a+b);
})(1,2); // 第二个小括号可以看做是调用函数
(function(a) {
console.log(a);
var num = 10;
}(5));
(function sum(a,b){
console.log(a+b);
var num = 10; //局部变量
}(3,5))
// 3. 立即执行函数最大的作用就是 独立创建了一个作用域,里面所有变量都是局部变量,不会有命名冲突的情况
</script>
</body>
3.元素滚动scroll系列
function getScroll() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
};
}
//使用的时候 getScroll().left
4.动画函数封装
<script>
var div = document.querySelector('div');
var span = document.querySelector('span')
function animate (obj,target) {
obj.timer = setInterval(() => { //给不同的元素指定了不同的定时器
if (obj.offsetLeft >= target) {
clearInterval(obj.timer)
}
obj.style.left = obj.offsetLeft + 50 + 'px';
}, 300);
}
animate(div,300)
animate(span,300)
</script>
function animate(obj, target, callback) {
console.log(callback);
// 当我们不断点击按钮,这个元素的速度会越来越快,因为开启了太多定时器
clearInterval(obj.timer)
obj.timer = setInterval(() => { //给不同的元素指定了不同的定时器
//步长值写到定时器的里面
// 把步长值改为整数 ,不要出现小数的问题
// var step = Math.ceil((target - obj.offsetLeft) / 10)
var step = (target - obj.offsetLeft) / 10
step = step > 0 ? Math.ceil(step) : Math.floor(step)
if (obj.offsetLeft == target) {
clearInterval(obj.timer)
// 回调函数写到定时器结束里面
if (callback) {
callback()
}
} else {
// 把每次加 1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
console.log(1);
}
}, 15);
}
//滑出盒子
<script src="./animate.js"></script>
<style>
* {
padding: 0;
margin: 0;
}
body {
height: 3000px;
}
.sliderbar {
position: fixed;
top: 300px;
right: 0px;
width: 50px;
height: 50px;
background-color: purple;
margin: 100px auto;
color: white;
line-height: 50px;
text-align: center;
font-size: 25px;
cursor: pointer;
}
/* .sliderbar:hover .con {
left: -150px;
}
.sliderbar:hover span {
transform: rotate(180deg)
} */
.sliderbar span {
/* display: block; */
position: relative;
z-index: 9;
/* transition: transform 0.2s ease-in-out; */
}
.con {
position: absolute;
top: 0;
left: 0;
background-color: purple;
height: 50px;
width: 200px;
/* transition: all 1s ease-in-out; */
}
</style>
</head>
<body>
<div class="sliderbar">
<span>←</span>
<div class="con">问题反馈</div>
</div>
<script>
var sliderbar = document.querySelector('.sliderbar');
var con = document.querySelector('.con');
sliderbar.addEventListener('mouseenter',function(){
animate(con,-150,function(){
sliderbar.children[0].innerHTML = '→'
})
})
sliderbar.addEventListener('mouseleave',function(){
animate(con,0,function(){
sliderbar.children[0].innerHTML = '←'
})
})
</script>
</body>
5. 常见网页特效案例
5.1pc轮播图
//防抖
function debounce (callback,delay) {
let timer = null;
ruturn function(...args) {
if(timer){
clearTimeout(timer)
}
timer = setTimeout(()=>{
callback.apply(this,args)
},delay)
}
}
// flag 节流阀
var flag = true;
arrow_r.addEventListener('click', function () {
if (flag) {
flag = false;
// 如果走到了最后复制的一张图片,此时 我们的 ul 要快速复原 ;left 改为 0
if (num == ul.children.length - 1) { //5-1=4
ul.style.left = 0;
num = 0
}
num++;
animate(ul, - num * focusWidth, function () {
flag = true;
})
// 8.点击右侧按钮, 小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放
// circle++;
// 先清除其余小圆圈的current类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下当前的小圆圈的current 类名
if (num == ul.children.length - 1) {
ol.children[0].className = 'current'
} else {
ol.children[num].className = 'current'
}
}
})
5.2 返回顶部案例
<!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>
* {
margin: 0;
padding: 0;
}
.w {
width: 1200px;
margin: 0 auto 20px;
}
.header {
height: 1000px;
background-color: red;
}
.banner {
height: 1000px;
background-color: royalblue;
}
.main {
height: 1000px;
background-color: slateblue;
}
.slider-bar {
position: absolute;
width: 100px;
height: 300px;
background-color: pink;
right: 5%;
top: 60%;
/* transform: translate(0,-50%); */
}
span {
display: none;
position: absolute;
bottom: 0;
width: inherit;
height: 30px;
background-color: lightcyan;
text-align: center;
line-height: 30px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="slider-bar">
<span class="goBack">返回顶部</span>
</div>
<div class="header w">头部区域</div>
<div class="banner w">banner区域</div>
<div class="main w">主体部分</div>
<script>
var slilder = document.querySelector('.slider-bar')
var main = document.querySelector('.main')
var goBack = document.querySelector('.goBack')
var mainTop = main.offsetTop;
var timer = null;
// console.log(mainTop);
document.addEventListener('scroll', function () {
//页面被减的头部
// console.log(window.pageYOffset);
if (window.pageYOffset >= 440) {
slilder.style.position = 'fixed'
slilder.style.top = 60 + 'px'
} else {
slilder.style.position = 'absolute'
slilder.style.top = '60%'
}
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
})
// goBack.addEventListener('click', function () {
// cancelAnimationFrame(timer);
// timer = requestAnimationFrame(function fn() {
// var oTop = window.pageYOffset;
// if (oTop > 0) {
// scrollTo(0, oTop - 50);
// timer = requestAnimationFrame(fn);
// } else {
// cancelAnimationFrame(timer);
// }
// });
// })
goBack.addEventListener('click', function () {
// animate(window,0);
window.scroll({
top: 0,
left: 0,
behavior: 'smooth'
});
})
// function animate(obj, target, callback) {
// // console.log(callback);
// // 当我们不断点击按钮,这个元素的速度会越来越快,因为开启了太多定时器
// clearInterval(obj.timer)
// obj.timer = setInterval(() => { //给不同的元素指定了不同的定时器
// //步长值写到定时器的里面
// // 把步长值改为整数 ,不要出现小数的问题
// // var step = Math.ceil((target - obj.offsetLeft) / 10)
// var step = (target - window.pageYOffset) / 10
// step = step > 0 ? Math.ceil(step) : Math.floor(step)
// if (window.pageYOffset == target) {
// clearInterval(obj.timer)
// // 回调函数写到定时器结束里面
// if (callback) {
// callback()
// }
// } else {
// // 把每次加 1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
// // obj.style.left = obj.offsetLeft + step + 'px';
// window.scroll(0, window.pageYOffset + step)
// }
// }, 15);
// }
</script>
</body>
</html>
5.3筋斗云案例
<style>
* {
margin: 0;
padding: 0;
}
ul {
position: relative;
list-style: none;
width: 800px;
height: 50px;
background-color: pink;
}
ul li {
position: relative;
z-index: 4;
float: left;
height: 50px;
padding: 0 15px;
line-height: 50px;
cursor: pointer;
}
div {
position: absolute;
width: 94px;
height: 50px;
background-color: green;
}
.current {
color: white;
}
</style>
</head>
<body>
<!-- 筋斗云案例 -->
<ul>
<li class="current">首页新闻</li>
<li>师资力量</li>
<li>活动策划</li>
<li>企业文化</li>
<li>招聘信息</li>
<li>公司简介</li>
<li>上海校区</li>
<li>广州校区</li>
<div class="mask"></div>
</ul>
<script>
var li = document.querySelectorAll('li')
var div = document.querySelector('div')
var current = 0;
for (let i = 0; i < li.length; i++) {
li[i].addEventListener('mouseenter', function () {
animate(div,this.offsetLeft)
})
li[i].addEventListener('mouseleave', function () {
// var current = document.querySelector('.current')
// animate(div,current.offsetLeft)
animate(div,current)
})
li[i].addEventListener('click',function(){
// div.style.left = this.offsetLeft + 'px';
for (var i =0;i<li.length;i++) {
li[i].className = '';
}
this.className = 'current';
current = this.offsetLeft;
})
}
function animate(obj, target, callback) {
// 当我们不断点击按钮,这个元素的速度会越来越快,因为开启了太多定时器
clearInterval(obj.timer)
obj.timer = setInterval(() => { //给不同的元素指定了不同的定时器
//步长值写到定时器的里面
// 把步长值改为整数 ,不要出现小数的问题
// var step = Math.ceil((target - obj.offsetLeft) / 10)
var step = (target - obj.offsetLeft) / 10
step = step > 0 ? Math.ceil(step) : Math.floor(step)
if (obj.offsetLeft == target) {
clearInterval(obj.timer)
// 回调函数写到定时器结束里面
if (callback) {
callback()
}
} else {
// 把每次加 1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
}
}, 15);
}
</script>
六、移动端网页特效
1.触屏事件
//元素拖动
div {
position: absolute;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
var div = document.querySelector('div')
var startX = 0;
var startY = 0;
var x = 0;
var y = 0;
div.addEventListener('touchstart', function (e) {
// 获取手指初始坐标
// console.log(event);
startX = e.targetTouches[0].pageX;
startY = e.targetTouches[0].pageY;
x = this.offsetLeft;
y = this.offsetTop;
})
div.addEventListener('touchmove', function (e) {
// 计算手指移动距离:手指移动之后的坐标减去手指初始坐标
// console.log(event);
var moveX = e.targetTouches[0].pageX - startX;
var moveY = e.targetTouches[0].pageY - startY;
// 移动我们的盒子 原来的位置 + 手指移动的距离
div.style.left = x + moveX+'px';
div.style.top = y + moveY+'px';
e.preventDefault() //注意拖动要阻止默认行为哦。不然会屏幕会滚动
})
</script>