admin管理员组文章数量:1588267
WebAPI
-
WebAPI
-
API: Application programming Interface,应用程序编程接口
-
Web API 提供的一套操作浏览器功能和页面元素的API
-
通过DOM接口可以改变网页的内容、解构和样式
-
DOM
-1 创建元素
- document.write
- innerHTML 常用
- createElement
-2 增加元素
- appendChild
- insertBefore
-3 删除元素
- removeChild
-4 修改元素
- 修改属性: src href title
- 修改普通元素内容: innerHTML innerText
- 修改表单元素: value type disabled
- 修改元素样式: style className
-5 查找元素
- DOM提供的API方法: getElementById getElementsByTagName
- H5提供的新方法: querySelector querySelectorAll 常用
- 利用节点操作获取元素: (父)parentNode (子)children previousElementSibling
nextElementSibling
-6 属性操作
- setAttribute 设置DOM属性
- getAttribute 得到DOM属性
- removeAttribute 移除属性
-7. 事件操作
- onclick
- onmouseover
- onmouseout
- onfocus
- onblur
- onmousemove
- onmouseup
- onmousedown
1.1 获取标签
1 web_API
#1_ DOM:Document Object Model
- 文档:一个页面就是一个文档,DOM中使用 document 表示
- 元素(element):页面中的所有的标签都是元素,元素可以看成是对象
- 节点(node):页面中所有的内容都是节点:标签,属性,文本
- 树状图(DOM树):由文档及文档中的所有的元素(标签)组成的一个树形结构图
--- #1 获取标签
-- document.getElementById("btn")
-- document.getElementsByTagName("p") //根据标签名字获取元素,返回的是一个伪数组
-- document.getElementsByTagName("a")[0]
-- document.getElementsByName("name属性的值") //根据name属性的值获取元素,返回来的是一个伪数组
-- document.getElementsByClassName("cls")
-- document.querySelector("#btn") //根据选择器获取元素,可以使用它们的 id, 类, 类型, 属性, 属性值等来选取元素
-- document.querySelector(".box") //万用属性获取元素,较常用
-- document.querySelector("li")
-- document.querySelectorAll(".cls") //根据选择器获取元素,返回来的是一个伪数组,里面保存了多个的DOM对象
-- var bodyEle = document.body // 返回body元素对象
-- var htmlEle = document.documentElement //返回html元素对象
-- #2节点操作,利用节点层次关系获取元素
- nodeType: 节点的类型,1---标签节点,2----属性节点,3---文本节点
- nodeName: 标签节点--大写的标签名字,属性节点---小写的属性名字,文本节点---#text
- nodeValue: 标签---null,属性---属性的值,文本---文本内容
- ulObj.parentNode.nodeType
- ulObj.parentNode.nodeName
- ulObj.parentNode.nodeValue
- dvObj.childNodes //获取子节点,包括元素节点,文本节点等
- var nodes=dvObj.childNodes[i]; //获取里面的每个子节点,返回一个集合
- if (nodes[i].nodeType == 1 && nodes[i].nodeName == "P") //判断这个子节点是不是p标签
- dvObj.children //只获取子元素节点,常用
- ulObj.children[0] //获取第一个子元素节点,常用
- ulObj.children[ul.children.length -1] //获取最后一个子元素节点,常用
- ulObj.firstElementChild //获取第一个子元素节点
- ulObj.lastElementChild
- .nextSibling //某个元素的后一个兄弟节点,包含文本节点,元素节点等等
- .previousSibling
- .nextElementSibling //后一个兄弟元素节点,常用
- .previousElementSibling
- 获取元素/节点操作对比
- ulObj.parentNode - ulObj.parentElement //父级节点 //父级元素
- ulObj.childNodes - ulObj.children
- ulObj.firstChild - ulObj.firstElementChild
- ulObj.lastChild - ulObj.lastElementChild
- .previousSibling - .previousElementSibling //某个元素的前一个兄弟节点;某个元素的前一个兄弟元素
- .nextSibling - .nextElementSibling//某个元素的后一个兄弟节点;某个元素的后一个兄弟元素
- 节点选择比元素选择多一个中间空白#text
- var node=dvObj.getAttributeNode("id"); //获取的是属性的节点
1.2 元素的样式操作
--- #2 元素的样式操作
-- JS 修改的 style 样式,产生的是行内样式,CSS 权重比较高
-- src,title,alt,href,id //操作基本标签的属性
-- name,value,type,checked,selected,disabled,readonly //操作表单标签的属性
-- .style.属性=值; //元素的样式操作
-- .className=值;
-- element.style 行内样式类操作
-- element.className 类名样式类操作,会覆盖原先类名,可以写多个保留原来的类名
-- img
- imObj.src="images/liuyan.jpg"; //设置图片的大小
- imObj.width="300";
- imObj.height="400";
- imObj.style.width = "300px";
- imObj.style.backgroundColor = "pink";
-- btn/a
- btnObj.innerText="设置文字";
- btnObj.href = "http://www.itcast";
- btnObj.checked=true;
- this.src=document.getElementById("ak").href;
- this.value.length
-- div
- dvObj.style.width = "300px";
- dvObj.style.backgroundColor = "yellow";
- dvObj.style.border = "10px solid red";
- dvObj.style.display="none";
- dvObj.display="block";
- dvObj.className="cls"; //设置类样式
-- 表单
- inputObJ.value = '设置输入框内的文字'
-- 伪数组
- 循环遍历这个数组,
- imgObjs[0].alt = "改了";
- imgObjs[0].title = "现实吧";
- inputs[i].value = "设置文字";
- inputs[i].type != "button";//判断
- imgObjs[i].onclick;
-inputs[i].value
1.3 元素内容操作
--- #3 元素内容操作
- pObjs[i].innerText="设置文字"; //直接显示,不识别html标签
- document.getElementsByTagName("p")[0].innerText //获取文本框的值
- textContent
- .innerHTML="<p>这是一个p</p>" //设置新的html标签内容,识别html标签。常用
-- 函数操作。常用
- imgObjs[i].onclick //注册点击事件
- list[i].onmouseover //注册事件
- list[i].onmouseout
- .onblur //注册失去焦点的事件
- .onfocus //注册获取焦点的事件
- return false //阻止超链接默认的跳转事件
-- 获取属性值
- element.属性 获取属性值,获取的是本身自带的属性值
- element.getAttribute('属性') 获取的是自定义的属性值
-- 设置属性值
- element.属性= '值' 获取属性值,获取的是本身自带的属性值
- element.setAttribute('属性','值') 获取的是自定义的属性值
-- 自定义属性
- list[i].setAttribute("score",(i+1)*10); /setAttribute("属性的名字","属性的值");
- this.getAttribute("score") /getAttribute("属性的名字")
- my$("dv").removeAttribute("score") / 移除自定义属性:removeAttribute("属性的名字")
- my$("dv").removeAttribute("class") /移除元素自带的样式属性
--H5自定义属性
- 为了保存并使用数据,data-开头作为属性并且赋值
- <div data-index= '1'></div>
- element.setAttribute('data-index',2) //设置属性
- element.getAttribute('data-index') //获取属性值
//dataset 是一个集合里面存放了所有以data开头的自定义属性,只能获取data-开头
- element.dataset.index //获取属性值
- element.dataset[ 'index' ] //获取属性值
1.4 元素的创建和移除
--- #4 元素的创建
-- document.write("标签代码及内容");
//如果在页面加载完毕后创建元素.页面中的内容会被干掉,会导致页面重绘
- document.write("<p>这是一个p</p>");
-- 父级对象.innerHTML="标签代码及内容"; //创建并插入
- my$("dv").innerHTML="<p>窗前明月光,疑是地上霜,举头望明月,低头思故乡</p>";
// 拼接字符串较耗时,数组方式可提高效率
-- document.createElement("标签名字"); //创建元素节点,常用
- var pObj = document.createElement("p"); //先创建,再插入
- divObj.appendChild(pObj)
- setInnnerText(元素对象,"元素内容"); //插入内容
- setInnnerText(pObj, "这是一个标签p");
- 父级元素.appendChild(子级元素对象); //添加节点,后面追加元素
- my$("dv").appendChild(obj)
//添加节点,选择位置追加元素
- 父级元素.inerstBefore(新的子级对象,参照的子级对象);
- my$("dv").insertBefore(obj,my$("dv").firstElementChild)
- 父级元素.removeChild(要干掉的子级元素对象); //删除节点
- my$("dv").removeChild(my$("dv").firstElementChild)
-- node.cloneNode() //克隆节点,默认只复制标签,不复制内容
-- var li = ul.children[0].cloneNode(true);
ul.appendChild(li);//括号内为true,为深拷贝,会复制节点本身以及里面所有的子节点
1.5 事件
--- #5 事件的绑定和解绑
-- 1. 对象.on事件名字=事件处理函数 /如果是多个相同事件注册用这种方式,最后一个执行,之前的被覆盖了
事件源.事件类型 = 事件处理程序
- my$("btn").onclick=function(){};
- onclick
- onmousenter
- onmouseover
- onmouseout
- onfocus
- onblur
- onmousemove
- onmouseup
- onmousedown
-- 为同一个元素绑定多个相同的事件
-- 2. 对象.addEventListener("没有on的事件名字",事件处理函数,false);
- my$("btn").addEventListener("click",function(){},false);
- my$("btn").addEventListener("click",f1,false);
- my$("btn").removeEventListener("click",f1,false); //解绑
- divs[0].onclick = null; //解绑
-- 3. 对象.attachEvent("有on的事件名字",事件处理函数); /仅IE8支持
- my$("btn").attachEvent("onclick",function(){});
- my$("btn").attachEvent("onclick",f1);
-- my$("btn").detachEvent("onclick",f1);
-- 事件对象
- event 是一个事件对象,是事件的一系列相关数据的集合
- div.addEventListener('click',function(event){
consoel.log(event);
})
- e.target 返回触发事件的对象
- e.currentTarget 返回触发事件的对象, ie6-8不兼容
- e.srcElement 返回触发事件的对象, ie6-8使用
- e.type 返回事件的类型,如 click mouseover 不带on
- e.cancelBubble 该属性阻止冒泡, ie6-8使用
- e.returnValue 该属性阻止默认事件,如不让链接跳转, ie6-8使用
- e.preventDefault() 该方法阻止默认事件,如不让链接跳转
- e.stopPropagation() 阻止冒泡,标准
-- 鼠标事件 mouseEvent -mousemove
- e.clientX 返回鼠标相对于浏览器窗口可视区域的X
- e.clientY 返回鼠标相对于浏览器窗口可视区域的Y
- e.pageX 返回鼠标相对于文档页面的 X 坐标,IE9+ 常用
- e.pageY 返回鼠标相对于文档页面的 Y 坐标,IE9+ 常用
- e.screenX 返回鼠标相对于电脑屏幕的 X 坐标
- e.screenY 返回鼠标相对于电脑屏幕的 Y 坐标
-mouseenter mouseenter不会冒泡,只会经过自身盒子触发
-mouseleave
-mouseover 会冒泡
-mouseout
-- 键盘事件
- onkeyup 某个键盘按键被松开时触发,不区分字母大小写
- onkeydown 某个键盘按键被按下时触发,不区分字母大小写
- onkeypress 某个键盘按键被按下时触发,不能识别功能键,区分字母大小写
- 执行顺序 keydown -- keypress -- keyup
- e.keyCode 相应键的ASCII值
-
-- 事件委托
- 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
- 案例: 给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器
-- 为同一个元素绑定多个不同的事件,指向相同的事件处理函数
- switch(e.type)-case
--- #6 事件冒泡
-- 多个元素嵌套,有层次关系,这些元素都注册了相同的事件,如果里面的元素的事件触发了,外面的元素的该事件自动的触发了.
-- document > html > body > div
-- e.stopPropagation(); // 谷歌和火狐支持
-- window.event.cancelBubble=true; // IE特有的
#3_ 思维
-- 动态选择效果 先设置好静态效果,再循环遍历注册元素点击事件,在点击时去清除样式和添加样式。
-- 排他功能 循环遍历每次点击设置一次属性值的初始化
-- 命名函数 如果是循环的方式添加事件,推荐用命名函数
-- 匿名函数 如果不是循环的方式添加事件,推荐使用匿名函数
--- #7 动画函数封装
-核心原理:通过定时器 setInterval() 不断移动盒子位置
1.5 事件实例代码
//1 阻止默认事件,让链接不跳转,或让提交按钮不提交
var a = document.querySelector('a');
a.addEventListener('click', function(e){
e.preventDefault();
})
//传统写法
a.onclick = function(e){
e.preventDefault(); //普通浏览器
e.returnValue; // 低版本浏览器 ie6~8
return false; // 但是return 后面的代码不执行
}
//2 阻止冒泡兼容方案
if (e && e.stopPropagation){
e.stopPropagation();
} else {
window.event.cancelBubble = true;
}
//3 事件监听
<ul>
<li>点击弹框</li>
<li>点击弹框</li>
<li>点击弹框</li>
<li>点击弹框</li>
<li>点击弹框</li>
</ul>
//事件委托核心原理:给父节点添加侦听器,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click',function(){
// alert('点击弹框');
// e.target 可以得到点击对象
e.target.style.backgroundColor = 'black';
})
//4 禁止复制页面中的文字
//1 contextmenu 禁止右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
//2 selectstart禁止选中文字
document.addEventListener('selectstart', function(e){
e.preventDefault();
})
//5 跟随鼠标移动的图标
//每次移动鼠标,能获取最新的鼠标坐标,把这个x和y坐标作为图片的top和left值就可以移动图片
//图片要移动距离,且不占位置,需使用绝对定位
<img src="images/angel.gif" alt="">
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function(e){
//1. mousemove 只要鼠标移动1px,就会触发事件
var x = e.pageX;
var y = e.pageY;
console.log('X坐标是' + x, 'Y坐标是' + Y);
pic.style.left = x - 50 + 'px'; // 坐标需要加 px 单位
pic.style.top = y - 40 + 'px';
})
</script>
//6 常用键盘事件
document.onkeyup = functon(){
console.log('keyup');
}
document.addEventListener('keyup', function(){
console.log('keyup');
})
document.addEventListener('keydown', function(){
console.log('keydown');
})
document.addEventListener('keypress', function(){
console.log('keypress');
})
//7 按下s键自动定位搜索框
//检测到用户按下了s键,就把光标定位到搜索框里面
<input type="text">
var search = document.querySelector('input');
document.addEventListener('keyup', function(e){
if(e.keyCode === 83){
search.focus();
}
})
//8 输入框上方显示放大内容
//给表单添加键盘事件,把表单内容值 value 获取过来赋值给放大盒子
<style>
/* 放大框下方小三角 */
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="请输入快递单号" class="jd">
</div>
</body>
<script>
//1 获取元素
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
//2 注册按键up事件,将值给 con
jd_input.addEventListener('keyup', function() {
if (this.value == '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
})
//3 失去焦点时,就隐藏con盒子
jd_input.addeventListener('blur',function(){
con.style.display = 'none';
})
//4 得到焦点时,就显示con盒子
jd_input.addeventListener('focus',function(){
if(this.value !== ''){
con.style.display = 'block';
}
})
</script>
1.6 元素实例代码
//1分时显示不同图片
<body>
<img src='images/a.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){
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>
//2用户登录框,切换登录框
//一个按钮两个状态,点击一次切换为文本框继续点击一次切换为密码框
<div class="box">
<label for="">
<img src="image/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(){
if (flag == 0){
pwd.type = 'text';
eye.src = 'images/open.png';
flag = 1;
} else {
pwd.type = 'password';
flag = 0;
}
}
</script>
//3点击关闭二维码图片
<div>
<img src="images/tao.png" alt="">
<i class="close-btn">X</i>
</div>
//1. 获取元素
var btn = document.querySelector('.close-btn');
var box = document.querySelector('.box');
//2. 注册事件,程序处理
btn.onclick = function(){
box.style.display = 'none'; //改变属性,隐藏
}
//4循环精灵图背景
//背景图为竖向排列的一个精灵图,让循环里边的i索引号*44就是每个图片的y坐标
//1.获取元素,所有的小 li
var lis = document.querySelectorAll('li');
for(var i = 0;i < lis.length;i++){
//让索引号乘以44,就是每个人 li 的背景y坐标
var index = i * 44;
lis[i].style.backgroundPosition = '0 -'+index+ 'px'; //(x y) (0 -44px)
}
//5显示隐藏文本框内容
//当鼠标点击文本框时,里面的文字隐藏,当鼠标离开文本框时,里面的文字显示
<input type="text" value="手机">
// 1. 获取元素
var text = document.querySelector('input');
// 2. 注册事件,获取焦点事件 onfocus
text.onfocus = function(){
if(this.value ==== '手机'){
this.value = '';
}
// 获得焦点时需要把文本框里面的文字颜色变黑
this.style.color = '#333';
}
//3. 注册事件,失去焦点事件 onblur
text.onblur = function(){
if(this.value === ''){
this.value = '手机'
}
// 失去焦点时需要把文本框里面的文字颜色变黑
this.style.color = '#999'
}
//6密码提示框显示
<div class="register">
<input type="password" class="ipt">
<p class="message">请输入6~16位密码</p>
</div>
//1. 获取元素
var pit = document.querySelector('.ipt');
var message = document.querySeletor('.message');
//2. 注册事件 失去焦点
ipt.onblur = function(){
// 根据表单里面值的长度 ipt.value.length
if (this.value.length <6 || this.value.length > 16){
message.className = 'messaga wrong';
message.innerHTML = '输入的位数要求是6~16位';
} else {
message.className = 'message right';
message.innerHTML = '您输入的正确!';
}
}
//7排他思路
//1. 获取所有的6个按钮标签
var btns = document.getElementsByTagName('button');
// btns 得到的是伪数组,
for(var i = 0; i< btns.length;i++){
btn[i].onclick = function(){
// 先把所有的按钮的背景色都去掉
for(var i = 0;i < btns.length;i++){
btns[i].style.backgroundColor = '';
}
// 然后设置当前点击的元素背景颜色
this.style.backgroundColor = 'pink';
}
}
//8点击切换背景图片
// 1. 获取元素
var imgs = document.querySelector('.baidu').querySelectorAll('img');
//2. 循环注册事件
for(var i = 0; i< imgs.length;i++){
imgs[i].onclick = function(){
// this.src 是点击图片的路径,把这个路径给 body
document.body.style.backgroundImage = 'url(' +this.src+ ')';
}
}
//9 hover表格行高亮
// 1.获取元素,获取 tbody 里面所有的行
var trs = document.querySelector('tbody').querySelectorAll('tr');
// 2. 利用循环绑定注册事件
for(var i = 0;i< trs.length;i++){
// 3.鼠标经过事件 onmouseover
trs[i].onmouseover = function(){
this.className = 'bg';
}
// 4.鼠标离开事件 onmuseout
trs[i].onmouseout = function(){
this.className = '';
}
}
//10 全选按钮
//1. 获取元素
var j_cbALL = document.getELememtById('j_cbAll');
var j_tbs = document.getELementById('j_tb').getElementByTagName('input');
//2. 注册事件
j_cbAll.onclick = function(){
for(var i =0;i< j_tbs.length; i++){
j_tbs[i].checked = this.checked; //this.checked获取当前复选框的选中状态
}
}
//3. 下面复选框需要全部选中,上面全选按钮才选中
//给下面每个复选框注册点击时事件,每次点击都循环判断4个小按钮是否全部选中
for(var i = 0; i < j_tbs.length;i++){
j_tbs[i].onclick = function(){
var flag = true; //flag 控制全选按钮是否选中
for(var i=0; i< j_tbs.length; i++){
// 每次点击下面的复选框都要循环检查4个小按钮是否全部被选中
if(!j_tbs[i].checked){
flag = false;
break //只要有一个没有选中,就退出for循环
}
}
j_cbAll.checked = flag;
}
}
//11 点击tab切换对应的内容
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<div class="item" style="display: block;">内容1</div>
<div class="item">内容2</div>
<div class="item">内容3</div>
<div class="item">内容4</div>
<div class="item">内容5</div>
</div>
</div>
</body>
<script>
// 获取元素
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
var items = document.querySelectorAll('.item');
// for 循环绑定点击事件
for (var i = 0; i < lis.length; i++) {
// 给5个小li设置索引号
lis[i].setAttribute('index', i);
lis[i].onclick() = function () {
for (var i = 0; i < lis.length; i++) {
lis[i].className = ''
}
this.className = 'current';
// 下面的显示内容模块
var index = this.getAttribute('index');
// 先让所有的div隐藏
for (var i = 0; i < items.length; i++) {
items[i].style.display = 'none';
}
//留下对应index的item显示出来
items[index].style.display = 'block';
}
}
</script>
//12 下拉菜单
<ul class="nav">
<!-- ul元素中包含4个li -->
<li>
<!-- 每个li元素中包含a和ul -->
<a href="#">微博</a>
<ul>
<li>
<a href="#">私信</a>
</li>
<li>
<a href="#">评论</a>
</li>
<li>
<a href="#">@我</a>
</li>
</ul>
</li>
</ul>
//鼠标经过li,里面的第二个孩子ul显示,鼠标离开,则ul隐藏
//1. 获取元素
var nav = document.querySelector('.nav');
var lis = nav.children; //得到4个小li
//2. 循环注册事件
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function () {
//获取第二个子元素节点
this.children[1].style.display = 'block';
}
lis[i].onmouseout = function () {
this.children[1].style.display = 'none';
}
}
//13 简单版发布留言案例
//点击按钮,动态创建一个li,添加到ul里面
<textarea name="" id="" cols="30" rows="10">评论内容</textarea>
<button></button>
<ul></ul>
//1.获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
//2.注册事件
btn.onclick = function () {
if (text.value == '') {
alert('请输入内容!');
return false;
} else {
//-1.创建元素
var li = document.createElement('li');
// 先有li 才能赋值,添加一个a标签
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
//-2.添加元素
//ul.appendChild(li); 添加到后面
ul.insertBefore(li, ul.children[0]); //添加到最前面
//-3.删除元素,删除的是当前的链接的父元素li
var as = document.querySelectorAll('a')
for (var i = 0; i > as.length; i++) {
as[i].onclick = function () {
//node.removeChild(child)
ul.removeChild(this.parentNode);
}
}
}
}
//14 依次删除元素
<body>
<ul class="nav">
<ul>
<li>元素1</li>
<li>元素2</li>
<li>元素3</li>
<li>元素4</li>
</ul>
</body>
<script>
// 1. 获取元素
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
// 2. 删除元素
// ul.removeChild(ul.children[0]);
// 3. 点击按钮依次删除里面的子元素
btn.onclick = function () {
if (ul.children.length == 0) {
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
}
</script>
//15 动态表格
<body>
<table cellspacing="0" border>
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 动态创建 -->
<!-- <tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr> -->
</tbody>
</table>
</body>
<script>
//1. 先准备好数据
var datas = [{
name: 'AAA',
subject: 'JavaScript',
score: 100
}, {
name: 'BBB',
subject: 'JavaScript',
score: 80
}, {
name: 'CCC',
subject: 'JavaScript',
score: 90
}, {
name: 'DDD',
subject: 'JavaScript',
score: 60
}];
//1.向tbody中创建行,根据数组长度创建行数
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
//创建tr行
var tr = document.createElement('tr');
tbody.appendChild(tr);
//2.行内创建单元格 td td的个数取决于每个对象里面的属性个数
for (var k in datas[i]) {
//创建单元格
var td = document.createElement('td');
// 把对象里面的属性值 datas[i][k] 给 td
td.innerHTML = datas[i][k]; //obj[k] 得到的是属性值
tr.appendChild(td);
}
//3. 创建有删除2个字的单元格
var td = document.createElement('td');;
td.innerHTML = '<a href="javascript:;">删除</a>';
tr.appendChild(td);
}
//4. 删除操作
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
// 点击a 删除当前a 所在的行,a链接的父元素的父元素
tbody.removeChild(this.parentNode.parentNode)
}
}
</script>
//16 innerHTML 数组方式创建大量元素,提高效率
// innerHTML 采用数组形式拼接,创建多个元素时效率更高
var inner = document.querySelector('.inner');
var arr = [];
for (var i=0;i<=100; i++){
arr.push('<a href="#">百度</a>')
}
inner.innerHTML = arr.join('') //把数组转换为字符串给inner
-
BOM
#2_ BOM:Browser Object Model 即浏览器对象模型,与浏览器窗口进行交互的对象
window
|
— document
|
— location
|
— navigation
|
— screen
|
— history— #1 系统对话框
- window.alert(“您好啊”);
- window.prompt(“请输入帐号”); //有返回值
— #2 窗口加载事件
- window.onload // 页面加载完毕执行
- window.onunload // 页面关闭后才触发的事件
- window.onbeforeunload // 页面关闭之前触发的
- window.onresize // 调整窗口大小加载事件
— #3 location对象中的属性和方法,获取或设置窗体的URL
-
window.location.hash //返回片段,地址栏上#及后面的内容,锚点
-
window.location.host //返回主机名及端口号
-
window.location.hostname //返回主机名
-
window.location.pathname //返回文件的路径—相对路径
-
window.location.port //返回端口号
-
window.location.protocol //返回协议
-
window.location.search //返回参数,搜索的内容
-
地址栏上的地址的操作
-
location.href=“http://www.jd”; //设置跳转的页面的地址
-
location.assign(“http://www.jd”); //记录浏览历史,可以实现后退功能
-
location.reload(); //重新加载–刷新
-
location.replace(“http://www.jd”); //没有历史记录
-
window.history.forward(); //历史记录的后退和前进
-
window.history.back();
-
window.navigator.userAgent /判断用户浏览器的类型
-
window.navigator.platform /判断浏览器所在的系统平台类型
— #4 API
-
定时器
-
setInterval(fn,time); clearInterval(timeId);
-
var timeId=window.setInterval(函数,间隔时间毫秒);
-
setTimeout(fn,time);
-
var timeId=window.setTimeout(fn,3000);
-
clearTimeout(timeId);
-
区别
-
setInterval(fn,time) 方法重复调用一个函数,每间隔这个时间,就去调用一次回调函数
-
随机数
-
var x = parseInt(Math.random() * 100 + 1);(0~99 1-100)
-
获取当前时间
-
var dt = new Date();
var hour = dt.getHours();
var second = dt.getSeconds(); -
this的指向问题
-
this的指向在函数定义时确定不了,一般情况下this最终指向的是那个调用它的对象
— #5 三组属性 offset scroll client
– offset系列:动态获取该元素的位置、大小。获得元素距离带有定位父元素的位置-
element.offsetParent:返回作为该元素带有定位的父级元素,如果父级元素没有定位则返回body
-
element.offsetWidth:返回 自身 包括padding、边框、内容区的宽度,返回数值不带单位
-
element.offsetHeight:返回 自身包括padding、边框、内容区的高度,返回数值不带单位
-
element.offsetLeft:返回元素相对带有定位父元素左边框的偏移
-
element.offsetTop:返回元素相对带有定位父元素上方的偏移
-
没有脱离文档流:
-
element.offsetLeft:父级元素margin+父级元素padding+父级元素的border+自己的margin
-
脱离文档流
-
是自己的left和自己的margin
– scroll系列:卷曲 -onscroll事件
- element.scrollWidth: 返回元素中 内容的 实际的宽(没有边框),如果没有内容就是元素的宽
- .scrollHeight: 返回元素中 内容的 实际的高(没有边框),如果没有内容就是元素的高
- element.scrollTop ;返回元素被向上卷曲出去的距离,数值不包含单位
- element.scrollLeft :返回元素向左卷曲出去的距离,数值不包含单位
- window.pageYOffset :页面被卷曲的距离 IE9+ //获取页面的滚动距离
- window.pageXOffset
– client系列:可视区域
- clientWidth:返回 自身 包括padding,内容区的宽度,不含边框,返回数值不带单位,常用
- clientHeight:返回 自身 包括padding,内容区的高度,不含边框,返回数值不带单位,常用
- clientLeft:左边边框的宽度
- clientTop :返回上面的边框的宽度
–总结
-返回 自身 的宽度
element.offsetWidth 内容区+padding+border
clientWidth 内容区+padding
element.scrollWidth 实际的宽度-- offset 常用于获取元素位置 offsetLeft offsetTop -- client 常用于获取元素大小 clientWidth clientHeight -- scroll 常用于获取滚动的距离 scrollTop scrollLeft
— #6 JS执行机制
- 先执行执行栈中的同步任务。
- 异步任务(回调函数)先放入任务队列中。
- 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
— #7 立即执行函数
- 不需要调用,立马能够自己执行的函数
- 作用:独立创建一个作用域,里面的变量都是局部变量,不会有命名冲突
-1. 第二个小括号可以看作是调用函数
()()
(function(a,b){
console.log(a)
})(1,2)
-2. (fn()())
(function sum(a,b){
console.log(a +b);
}(2,3));
2.1 实例代码
//1 5秒之后关闭广告
<img src="images/ad.jpg" alt="" class="ad">
var ad = document.querySelector('.ad');
setTimeout(function(){
ad.style.display = 'none';
}, 5000)
//2 倒计时效果
//倒计时不断变化,使用setInterval使其自动变化
<body>
<div class="search">
<span class="day">0</span>
<span class="hour">0</span>
<span class="minute">0</span>
<span class="second">0</span>
</div>
</body>
<script>
//1 获取元素
var day = document.querySelector('.day');
var hour = document.querySelector('.hour');
var minute = document.querySelector('.minute');
var second = document.querySelector('.second');
// 获取的是用户输入时间的总的毫秒数
var inputTime = +new Date('2020-3-5 16:40:00');
countDown(); //先调用一次,去掉开启空白
//2 开启定时器
setInterval(countDown, 1000);
function countDown(time) {
var nowTime = +new Date(); //返回的是当前时间的总的毫秒数
//var inputTime = +new(time); //返回的是用户输入时间的总的毫秒数
var times = (inputTime - nowTime) / 1000; //times 是剩余时间总的秒数
var d = parseInt(times / 60 / 60 / 24); //天
d = d < 10 ? '0' + d : d;
var h = parseInt(times / 60 / 60 % 24); //时
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 60 % 60); //分
m = m < 10 ? '0' + m : m;
var s = parseInt(times % 60); // 当前的秒
s = s < 10 ? '0' + s : s;
day.innerHTML = d;
hour.innerHTML = h;
minute.innerHTML = m;
second.innerHTML = s;
//return d + '天' + h + '时' + m + '分' + s + '秒';
}
//console.log(countDown('2019-5-1 18:00:00'));
</script>
//3 开启和关闭定时器
<button class="begin">开启定时器</button>
<button class="stop">关闭定时器</button>
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
var timer = null; //全局变量,null 是一个空对对象
begin.addEventListener('click',function(){
timer = setInterval(function(){
console.log('定时器已开启');
}, 1000);
})
stop.addEventListener('click', function(){
clearInterval(timer);
})
//4 定时控制输入框
//点击按钮,禁用按钮,显示倒计时
<body>
手机号码: <input type="tel"> <button>发送</button>
</body>
<script>
var btn = document.querySelector('button');
var time = 3; //定义剩下的秒数
//1点击按钮,禁用disabled
btn.addEventListener('click', function() {
btn.disabled = true;
//添加定时器,在定时器内修改按钮内容
var timer = setInterval(function() {
//3如果变量为0,停止定时器,复原按钮
if (time == 0) {
//4清除定时器和复原按钮
clearInterval(timer);
btn.disabled = false;
btn.innerHTML = '发送';
time = 3;
} else {
//2按钮内的内容发生变化
btn.innerHTML = '还剩下' + time + '秒';
time--;
}
}, 1000);
})
</script>
//5 使用URL传递参数
//第一个登陆页面,里面有提交表单,action提交到 index.html页面
//第二个页面使用第一个页面的参数,实现数据在不同页面之间传递
-login.html
<body>
<form action="index.html">
用户名:<input type="text" name="uname">
<input type="submit" value="登陆">
</form>
</body>
-index.html
<script>
console.log(location.search);// ?uname=andy
//1 先去掉? substr('起始的位置',截取几个字符串)
var params = location.search.substr(1);
//2 利用=把字符串分割为数组 split('=')
var arr = params.split('='); //['uname','andy']
//3 把数据写入div
var div = document.querySelector('div');
div.innerHTML = arr[1] + '欢迎您';
</script>
//6 计算鼠标在盒子内的坐标
//在盒子内点击,想要得到鼠标距离盒子左右的距离
//鼠标在页面中的坐标 (e.pageX, e.pageY)
//得到盒子在页面中距离 (box.offsetLeft, box.offsetTop)
var box = document.querySelctor('.box');
box.addEventListener('click', function(e){
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x坐标是' + x + 'y坐标是' +y;
})
//7 模态框拖拽
//页面中的弹出框随鼠标拖拽
//鼠标的坐标减去鼠标在盒子内的坐标,才是模态框真正的位置
<script>
// 1. 获取元素
var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
// 2. 点击弹出层这个链接,让 mask 和 login显示出来
link.addEventListener('click', function() {
mask.style.display = 'block';
login.style.display = 'block';
});
// 3. 点击 closeBtn 就隐藏 mask 和 login
closeBtn.addEventListener('click', function() {
mask.style.display = 'none';
login.style.display = 'none';
})
// 4. 开始拖拽
//-1 当鼠标按下,就获得鼠标在盒子内的坐标
title.addEventListener('mousedown', move);
function move(e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
//-2 鼠标移动的时候,把鼠标在页面中的坐标,减去鼠标在盒子内的坐标就是模态框的left和top
document.addEventListener('mousemove', function(e) {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
});
//-4 鼠标弹起,移除鼠标移动事件
document.addEventListener('mouseup', function() {
document.removeEventListener('mouseover', move);
})
}
</script>
//8 放大镜效果
//-1.鼠标经过小图片盒子,黄色的遮挡快和大盒子显示,离开隐藏2个盒子功能
//-2.黄色的遮挡层跟随鼠标移动
//-3.移动黄色遮挡层,大图片跟随移动功能
<body>
<div class="preview_wrap">
<img src="upload/s3.png" alt="">
<div class="mask" style: "display: none"></div>
<div class="big" style: "display: none">
<img src="upload/big.jpg" alt="" class="bigImg">
</div>
</div>
</body>
<script>
//0. 页面加载完后执行
window.addEventListener('load', function() {
var preview_img = document.querySelector('.preview_img');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
//1. 当鼠标经过 preview_img 就显示和隐藏 mask遮挡层 和 big 大盒子
preview_img.addEventListener('mouseover', function() {
mask.style.display = 'block';
big.style.display = 'block';
})
preview_img.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
})
//2. 鼠标移动的时候,让黄色的盒子跟着鼠标来走
preview_img.addEventListener('mousemove', function(e) {
//2.1 先计算出鼠标在盒子内的坐标
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
//2.2让鼠标处于mask的中间, 鼠标的坐标减去mask值的一半
//mask.style.left = x - mask.offsetWidth / 2 + 'px';
//mask.style.top = y - mask.offsetHeight / 2 + 'px';
//2.3 抽取判断
var maskX = x - mask.offsetWidth / 2
var maskY = y - mask.offsetHeight / 2 + 'px';
//2.4 如果小于零,把坐标设置为0,如果大于遮挡层最大的移动距离,就把坐标设为最大的移动距离
var maskMax = preview_img.offsetHeight - mask.offsetHeight;;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= preview_img.offsetWidth - mask.offsetWidth) {
maskX = preview_img.offsetWidth - mask.offsetWidth;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= preview_img.offsetHeight - mask.offsetHeight) {
maskY = preview_img.offsetHeight - mask.offsetHeight;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// mask 移动距离/mask 最大移动距离 = 大图片移动距离/大图片最大移动距离
//3.大图片移动距离 = mask 移动距离*大图片移动距离/mask 最大移动距离
var bigImg = document.querySelector('.bigImg');
//大图片最大移动距离
var bigMax = bigImg.offsetWidth - big.offsetWidth;
//大图片移动距离
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigImg.style.left = -bigX + 'px';
bigImg.style.top = -bigY + 'px';
})
})
</script>
//9 flexible 分析
(function flexible(window, document) {
// 获取HTML根元素
var docEl = document.documentElement
// dpr 物理像素比
var dpr = window.devicePixelRatio || 1
// adjust body font size
// 设置body的字体大小
function setBodyFontSize() {
//如果页面有body这个元素,就设置body的字体大小
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
} else {
//如果没有body,则等着页面主要的DOM元素加载完毕再去设置body的字体大小
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
// 设置 html 元素的大小
function setRemUnit() {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
// 当页面尺寸大小发生变化的时候,要重新设置 rem的大小
window.addEventListener('resize', setRemUnit)
// pageshow 事件,页面重新加载事件
window.addEventListener('pageshow', function(e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
//有的移动端的浏览器不支持0.5像素的写法
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
//10 仿淘宝固定右侧边栏
// 原先是绝对定位,当页面滚动到一定位置,侧边栏改为固定定位,页面继续滚动,显示返回顶部按钮
// 需要用到页面滚动事件 scroll 因为是页面滚动,所以事件源是 document,滚动到某个位置,就去判断页面被卷去的上部值
// 元素被卷去的头部是 element.scrollTop, 页面被卷去的头部则是 window.pageYOffset
<body>
<div class="slider-bar">
<span class="goBack" style: "display: none">返回顶部</span>
</div>
<div class="header">头部区域</div>
<div class="banner">banner区域</div>
<div class="main">主体部分</div>
</body>
<script>
// 1. 获取元素
var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
var main = document.querySelector('.main');
var goBack = document.querySelector('.goback');
// 先计算出被卷曲头部的大小
var bannerTop = banner.offsetTop;
var mainTop = main.offsetTop;
// 侧边栏固定定位之后应该变化的数值
var sliderTop = sliderbar.offsetTop - bannerTop;
// 2. 页面滚动事件,滚动到banner
document.addEventListener('scroll', function() {
if (window.pageYOffset >= bannerTop) {
sliderbar.style.position = 'fixed';
sliderbar.style.top = sliderTop + 'px';
} else {
sliderbar.style.position = 'absolute';
sliderbar.style.top = "300px";
}
// 页面滚动,滚动到main
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
})
</script>
//11 简单动画
<div>盒子</div>
div{
position: absolute;
left: 0;
width: 100px;
height: 100px;
background-color: black;
}
var div = document.querySelector('div');
var timer = setInterval(function() {
if (div.offsetLeft >= 400){
//停止定时器,即停止动画
clearInterval(timer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 30);
//12 动画函数封装
<style>
div {
position: absolute;
left: 0;
width: 100px;
height: 100px;
background-color: black;
}
</style>
<body>
<div>123</div>
</body>
<script>
function animate(obj, target) {
var timer = setInterval(function() {
if (div.offsetLeft >= target) {
clearInterval(timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
var div = document.querySelector('div');
animate(div, 300);
</script>
//13 动画函数封装优化
function animate(obj, target) {
//让元素只有一个定时器,先清除以前的定时器,只保留当前一个定时器
clearInterval(obj.timer);
// 将timer添加为对象的属性,节省内存空间
obj.timer = setInterval(function() {
if (obj.offsetLeft >= target) {
clearInterval(obj.timer );
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
var div = document.querySelector('div');
animate(div, 300);
//14 缓动动画封装
//让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
//核心算法: (目标值 - 现在的位置) / 10 做为每次移动的距离步长
<script>
function animate(obj, target) {
//让元素只有一个定时器,先清除以前的定时器,只保留当前一个定时器
clearInterval(obj.timer);
// 将timer添加为对象的属性,节省内存空间
obj.timer = setInterval(function() {
// 步长值写到定时器里面,并取整数.判断正负数,正则取大,负则取小
//var step =Math.ceil()
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
var div = document.querySelector('div');
animate(div, 500);
</script>
//15 动画封装添加回调函数
<script>
function animate(obj, target, callback) {
//让元素只有一个定时器,先清除以前的定时器,只保留当前一个定时器
clearInterval(obj.timer);
// 将timer添加为对象的属性,节省内存空间
obj.timer = setInterval(function() {
// 步长值写到定时器里面,并取整数.判断正负数,正则取大,负则取小
//var step =Math.ceil()
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();
// }
callback && callback();
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
var div = document.querySelector('div');
var btn = document.querySelector('button');
animate(div, 500);
btn800.addEventListener('click', function() {
animate(div, 800, function() {
alert('结束了!');
div.style.backgroundColor = 'red';
});
})
</script>
3 PC网页特效
- 节流阀
- 防止轮播图按钮连续点击造成播放过快
- 目的: 让上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发
- 思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数
开始设置一个变量 var flag = true;
if (flag){ flag=false; do something} 关闭水龙头
利用回调函数,动画执行完毕, flag=true 打开水龙头
3.1 实例代码
//1 鼠标经过 silderbar 让con盒子滑动出来
<body>
<div class="sliderbar">
<span>⬅</span>
<div class='con'>问题反馈</div>
</div>
</body>
<script>
//1. 获取元素
var sliderbar = document.querySelector('.sliderbar');
var con = document.querySelector('.con');
sliderbar.addEventListener('mouseenter', function() {
animate(con, -160, function() {
sliderbar.children[0].innerHTML = '→';
});
})
sliderbar.addEventListener('mouseleave', function() {
animate(con, 0, function() {
sliderbar.children[0].innerHTML = '⬅';
})
})
</script>
//2 网页轮播图-综合案例
<body>
<div class="w">
<div class="main">
<div class="focus fl">
<!-- 左侧按钮 -->
<a href="javascript:;" class="arrow-l"></a>
<!-- 右侧按钮 -->
<a href="javascript:;" class="arrow-r"></a>
<!-- 核心滚动区域 ul宽度为600%,子绝对定位,父overflowhiden-->
<ul>
<li>
<a href="#"><img src="upload/focus1.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="upload/focus2.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="upload/focus3.jpg" alt=""></a>
</li>
</ul>
<!-- 小圆圈 -->
<ol class="circle">
<li></li>
<li class="current"></li>
<li></li>
</ol>
</div>
</div>
</div>
</body>
<script>
window.addEventListener('load', function () {
//1 获取元素
var arrow_l = document.querySelector('.arrow-l');
var arrow_r = document.querySelector('.arrow-r');
var focus = document.querySelector('.focus');
//2 鼠标经过 focus 就显示隐藏左右按钮
focus.addEventListener('mouseenter', function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
//11.1 鼠标经过时定时器清除
clearInterval(timer);
timer = null; //清除定时器变量
})
focus.addEventListener('mouseleave', function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
});
//3 动态生成小圆圈,有几张图片,就生成几个小圆圈
var ul = focus.querySelector('ul');
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
//5.1 记录当前小圆圈的索引号,通过自定义属性来做
li.setAttribute('index', i);
ol.appendChild(li);
//4 排他思想,绑定点击事件
li.addEventListener('click', function () {
// 清除所有的小li的类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 当前的li 设置 current 类名
this.className = 'current';
//5 点击小圆圈,移动图片。移动距离为索引号乘以图片的宽度
//5.2 点击时拿到当前li 的index;
var index = this.getAttribute('index');
//9.1 点击某个li,要把li的左引号给 num
num = index;
//9.2 点击某个li,要把li的索引号给 circle
circle = index;
var focusWidth = focus.offsetWidth;
animate(ul, -index * focusWidth);
})
}
//3.1 把ol中的第一个li设置类名为 current
ol.children[0].className = 'current';
//6 克隆第一张图片li 放到ul 后面
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
//7 点击右侧按钮,图片滚动一张
var num = 0;
// 8.1 circle 控制小圆圈的播放
var circle = 0;
//12 添加节流阀
var flag = true;
arrow_r.addEventListener('click', function () {
if (flag) {
flag = false; //关闭节流阀
//7.1 在最后添加第一张图片,如果走到了最后复制的一张图片
//ul快速复原 left 改为 0;
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth, function () {
flag = true; //动画播放完毕关闭节流阀
});
// 8. 点击右侧按钮,小圆圈跟随一起变化
circle++;
// 如果 cirle=4,说明走到了最后克隆的这张图片,就复原
if (circle == ol.children.length) {
circle = 0;
}
circleChange();
// //8.2 先清除其余小圆圈的current 类名
// for (var i = 0; i < ol.children.length; i++) {
// ol.children[i].className = '';
// }
// //8.3 留下当前的小圆圈的currnet类名
// ol.children[circle].className = 'current';
}
});
//10.
arrow_l.addEventListener('click', function () {
if (flag) {
flag = false; //关闭节流阀
//7.1 在最后添加第一张图片,如果走到了最后复制的一张图片
//ul快速复原 left 改为 0;
if (num == 0) {
// ul.style.left = (ul.children.length - 1) * focusWidth + 'px';
// num = ul.children.length - 1;
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWisdth, function () {
flag = true; //动画播放完毕关闭节流阀
});
// 8. 点击右侧按钮,小圆圈跟随一起变化
circle--;
// 如果circle<0 说明走到了第一张图片,则小圆圈要改为第4个
// if (circle < 0) {
// circle = ol.children.length - 1;
// }
circle = circle < 0 ? ol.children.length - 1 : circle;
circleChange();
}
});
// 重复代码,抽离出来
function circleChange() {
//8.2 先清除其余小圆圈的current 类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
//8.3 留下当前的小圆圈的currnet类名
ol.children[circle].className = 'current';
}
//11 自动播放功能
var timer = setInterval(function () {
//手动调用点击事件
arrow_r.click();
}, 2000);
})
</script>
//3 返回顶部
// 滚动窗口文档中的特定位置,window.scroll(x,y)
// 当点击了返回顶部模块,就让窗口滚动到页面的最上方
goBack.addEventListener('click', function(){
// x y 不跟单位,直接写数字
window.scroll(0,0);
//窗口滚动,对象是window
animate(window,0);
})
//改为上下滚动函数
function animate(obj, target, callback) {
//让元素只有一个定时器,先清除以前的定时器,只保留当前一个定时器
clearInterval(obj.timer);
// 将timer添加为对象的属性,节省内存空间
obj.timer = setInterval(function() {
// 步长值写到定时器里面,并取整数.判断正负数,正则取大,负则取小
//var step =Math.ceil()
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();
// }
callback && callback();
}
//obj.style.left = window.pageYOffset + step + 'px';
window.scroll(0, window.pageYOffset + step);
}, 15);
}
//4 筋斗云特效
// 鼠标进过某个小li,筋斗云会飞到当前小li的位置,鼠标离开,筋斗云复原
// 鼠标点击某个小li,筋斗云就会留在点击的这个小li的位置
<body>
<div id="c_nav" class="c-nav">
<span class="cloud"></span>
<ul>
<li class="current"><a href="#">首页新闻</a></li>
<li>
<a href="#">师资力量</a>
</li>
<li>
<a href="#">活动策划</a>
</li>
<li>
<a href="#">企业文化</a>
</li>
<li>
<a href="#">招聘信息</a>
</li>
<li>
<a href="#">公司介绍</a>
</li>
<li>
<a href="#">小猪佩奇</a>
</li>
</ul>
</div>
</body>
<script>
window.addEventListener('load', function() {
//1. 获取元素
var cloud = document.querySelector('.cloud');
var c_nav = document.querySelector('.c-nav');
var lis = document.querySelector('.li');
//2. 给所有的小 li 绑定事件
// 这个 current 作为筋斗云的起始位置
var current = 0;
for (var i = 0; i < lis.length; i++) {
// 鼠标经过当前li的位置作为目标值
lis[i].addEventListener('mouseenter', function() {
animate(cloud, this.offsetLeft);
});
// 鼠标离开,复原为0/curent
lis[i].addEventListener('mouseleave', function() {
animate(cloud, current);
});
//当鼠标点击,把当前位置作为目标值
lis[i].addEventListener('click', function() {
current = this.offsetLeft;
})
}
})
</script>
4 移动端网页特效
-
触屏事件 -touch
-touchstart 手指触摸到一个元素时触发
-touchmove 手指从一个DOM元素上滑动时触发
-touchend 手指从一个DOM元素上移开时触发 -
触摸事件对象 TouchEvent
-touches 手指触摸屏幕的所有的手指的一个列表
-targetTouches 正在触摸当前 DOM 元素上的手指的一个列表
-changedTouches 手指状态发生了改变的列表,从无到有变化 -
H5新属性 — classList
-返回元素的类名,可以用来在元素中添加,移除,切换CSS类 -
移动端 click 事件会有 300ms 的延时,因为移动端屏幕双击会缩放(double tap to zoom)页面
解决方案:- 禁用缩放
-
插件
----fastclick插件解决 300 ms延迟if (‘addEventListener’ in document) {
document.addEventListener(‘DOMContentLoaded’, function() {
FastClick.attach(document.body);
}, false);
}----Swiper 插件
----superslide 插件
----isscroll 插件
----zy.media.js 视频插件
-
移动端常用开发框架
-
本地存储
```javascript
-1
window.sessionStorage- 生命周期为关闭浏览器窗口,关闭窗口就删除
- 在同一个窗口下数据可以共享
- 以键值对的形式储存使用
//示例
var ipt = document.querySelector(‘input’);
var set = document.querySelector(’.set’);
var get = document.querySelector(’.get’);
var remove = document.querySelector(’.remove’);
set.addEventListener(‘click’ function(){
var val = ipt.value;
sessionStorage.setItem(‘uname’,val);
})
get.addEventListener(‘click’ function(){
consoel.log(sessionStorage.getItem(‘uname’));
})
remove.addEventListener(‘click’ function(){
sessionStorage.removeItem(‘uname’);
})
//清除所有sessionStorage
del.addEventListener(‘click’ function(){
sessionStorage.clear();
})
-2
window.localStorage - 生命周期永久生效,除非手动删除,即使页面关闭也会存在
- 同一浏览器可以多窗口页面共享
- 以键值对的形式储存使用
//示例
//示例
var ipt = document.querySelector(‘input’);
var set = document.querySelector(’.set’);
var get = document.querySelector(’.get’);
var remove = document.querySelector(’.remove’);
set.addEventListener(‘click’ function(){
var val = ipt.value;
localStorage.setItem(‘uname’,val);
})
get.addEventListener(‘click’ function(){
consoel.log(localStorage.getItem(‘uname’));
})
remove.addEventListener(‘click’ function(){
localStorage.removeItem(‘uname’);
})
//清除所有sessionStorage
del.addEventListener(‘click’ function(){
localStorage.clear();
})
4.1实例代码
1 触摸事件示例
//获取元素
var div = document.querySelector('div');
// 手指触摸DOM元素事件
div.addEventListener('touchstart', function() {
console.log('触摸事件触发')
})
// 手指在DOM元素上移动事件
div.addEventListener('touchmove', function(){
console.log('触摸事件持续')
})
// 手指在离开DOM元素事件
div.addEventListener('touchend', function(){
console.log('触摸事件结束')
})
//classList示例
var div = document.querySelector('div');
//1.添加类名
div.classList.add('three');
//2.删除类名
div.classList('one');
//3.切换类名
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
document.body.classList.toggle('bg');
})
2. div随手指移动
// 手指移动中,计算出手指移动的距离。然后用盒子原来的位置+手指移动的距离
//手指移动距离,手指滑动中的位置减去手指刚开始触摸的位置
var div = document.querySelector('div');
var startX = 0; //获取手指初始坐标
var startY = 0;
var x = 0; //获得盒子原来的位置
var y = 0;
div.addEventListener('touchstart', function(e){
startX = e.targetTouches[0].pageX;
startY = e.targetTouches[0].pageY;
x = ths.offsetLeft;
y = this.offsetTop;
});
div.addEventListener('touchmove', function(e){
// 计算手指的移动距离: 手指移动之后的坐标减去手指初始的坐标
var moveX = e.targetTouches[0].pageX - startX;
var moveY = e.targetTouches[0].pageY - startY;
this.style.left = x + moveX + 'px';
this.style.top = y + moveY + 'px';
e.preventDedault(); //阻止屏幕滚动的默认行为
})
3. 移动端轮播图
<body>
<div class="focus">
<ul>
<!-- 31231 -->
<li><img src="upload/focus1.jpg" alt=""></li>
<li><img src="upload/focus2.jpg" alt=""></li>
<li><img src="upload/focus3.jpg" alt=""></li>
</ul>
<ol>
<li></li>
<li></li>
<li></li>
</ol>
</div>
</body>
<script>
window.addEventListener('load', function () {
// 1.获取元素
var focus = document.querySelector('.focus');
var ul = focus.children[0];
// 获得focus的宽度
var w = focus.offsetWidth;
// 2. 利用定时器自动轮播图片
var index = 0;
var timer = setInterval(function () {
index++;
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + ' + "px")';
}, 2000);
// 3.过渡完成后再去判断,监听过渡完成的事件 transitionend
ul.addEventListener('transitionend', function () {
// 无缝滚动
if (index >= 3) {
index = 0;
//去掉过渡效果,让 ul 快速的跳到目标位置
ul.style.transition = 'none';
// 利用最新的索引号乘以宽度去滚动图片
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + ' + "px")';
} else if (index < 0) {
index = 2;
//去掉过渡效果,让 ul 快速的跳到目标位置
ul.style.transition = 'none';
// 利用最新的索引号乘以宽度去滚动图片
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + ' + "px")';
}
// 4. 小圆点跟随变化
// 把ol里面的li带有current类名的选出来去掉类名
ol.querySelector('.current').classList.remove('.current');
// 让当前索引号的小 li 加上 current
ol.children[index].classList.add('.current');
});
//5 手指滑动轮播图
// 触摸元素 touchstart: 获取手指初始坐标
var startX = 0;
var moveX = 0;
var flag = false;
ul.addEventListener('touchstart', function (e) {
startX = e.targetTouches[0].pageX;
//手指触摸的时候就停止定时器
clearInterval(timer);
});
//6 移动手指 touchmove: 计算手指的滑动距离,并且移动盒子
ul.addEventListener('touchmove', function (e) {
// 计算移动距离
moveX = e.targetTouches[0].pageX - startX;
// 移动盒子: 盒子原来的位置 + 手指移动的距离
var translateX = -index * w + moveX;
ul.style.transition = 'none';
ul.style.transform = 'translateX(' + translatex + ' + "px")';
flag = true; // 如果用户手指移动过再去判断,否则不做判断效果
e.preventDefault(); // 阻止屏幕移动事件
});
//手指离开,根据移动距离去判断是回弹还是播放上一张下一张
ul.addEventListener('touchend', function (e) {
if (flag) {
//-1 如果移动距离大于50就播放上一张或下一张
if (Math.abs(moveX) > 50) {
if (moveX > 0) {
index--;
} else {
index++;
}
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)'
} else {
//小于50,返回原来的位置
var translatex = -index * w;
ul.style.transition = 'all .1s';
ul.style.transform = 'translateX(' + translatex + 'px)'
}
}
//手指离开重新开启定时器
clearInterval(timer);
var timer = setInterval(function () {
index++;
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + ' + "px")';
}, 2000);
});
})
</script>
4. 点击按钮返回顶部
<style>
.goBack {
display: none;
position: fixed;
bottom: 50px;
right: 20px;
width: 38px;
height: 38px;
background: url(../images/back.png) no-repeat;
background-size: 38px 38px;
}
</style>
<body>
<div class="boBack"></div>
</body>
<script>
var goBack = document.querySelector('.goBack');
var nav = document.querySelector('nav');
window.addEventListener('scroll', function() {
if (window.pageYOffset >= nav.offsetTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
});
goBack.addEventListener('click', function() {
window.scroll(0, 0);
})
</script>
5. 记住用户名
//永久储存 使用localStorage
<body>
<div>
<input type="text" id="username"><input type="checkbox" name="" id="remember">记住用户名
</div>
</body>
<script>
var username = document.querySelector('#username');
var remember = document.querySelector('#remember');
if (localStorage.getItem('username')) {
username.value = localStorage.getItem('username');
remember.checked = true;
}
//复选框发生改变时判断
remember.addEventListener('change', function() {
if (this.checked) {
localStorage.setItem('username', username.value);
} else {
localStorage.removeItem('username');
}
})
</script>
5.底部线
本文标签: WebAPI
版权声明:本文标题:-3 WebAPI 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1728026484a1142711.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论