1、事件对象的常见的属性和方法
事件对象属性和方法 | 说明 |
e.target | 返回触发的事件对象(标准) |
e.srcElement | 返回触发的事件对象(非标准,IE6-8使用) |
e.type | 返回事件类型,比如click,mouseover等,注意不带on开头 |
e.cancelBubble | 该属性阻止冒泡,非标准ie6-8使用 |
e.returnValue | 该属性阻止默认事件(默认行为,非标准ie6-8使用,比如不让链接跳转 |
e.preventDefault() | 该方法阻止默认事件(默认行为),标准,比如不让链接跳转 |
e.stopPropagation() | 阻止事件冒泡,标准 |
<button>按钮1</button>
<button>按钮2</button>
<a href="http://baidu.com">百度</a>
<script>
var button = document.querySelectorAll("button");
// 输出事件对象
button[0].addEventListener("click", function (event) {
console.log(event.target); //target意思是目标,获取元素button[0]
});
// 阻止默认行为,这里阻止a链接跳转到百度
document.querySelector("a").onclick = function (e) {
e.preventDefault();
};
// 阻止冒泡
document.querySelectorAll("button")[1].onclick = function (e) {
e.stopPropagation();
};
document.onclick = function () {
console.log("如果存在事件冒泡,这里就会被触发");
};
</script>
2、DOM_e.target和this的区别
e.target指向的是触发事件的对象
this指向的是注册事件的对象
解释区分:如果注册事件是ul标签,然后因为事件冒泡原因,点击li标签后触发ul事件
这时e.target就是li,this就是ul标签
代码区分:
<ul>
<li>知否知否</li>
<li>知否知否</li>
<li>知否知否</li>
<li>知否知否</li>
</ul>
<script>
var ul = document.querySelector("ul");
ul.addEventListener("click", function (e) {
console.log(this); //返回的是绑定事件的对象,这里也就是ul元素
console.log(e.target); //返回的是触发事件的对象或者理解成点击了谁,比如点击li就是li是触发事件的对象
});
</script>
3、事件委派
事件委托:事件委托也称为是事件代理,在jquery里面称为是事件委托
事件委托原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其共同的父元素上,然后利用事件冒泡的原理设置到每个子节点上
简单解释:给ul注册点击事件,利用事件对象的target来找到当前点击的li,因为点击li事件会冒泡到ul上,ul由注册事件就会被触发
事件委托的作用:只需要操作一次DOM,提高程序性能
<ul>
<li>知否知否,应是绿肥红瘦。</li>
<li>知否知否,应是绿肥红瘦。</li>
<li>知否知否,应是绿肥红瘦。</li>
</ul>
<script>
var ul = document.querySelector("ul");
ul.addEventListener("click", function (e) {
console.log(e.target.innerText);
e.target.style.backgroundColor = "red";
});
</script>
4、DOM_禁用右键菜单和禁用选中文字事件
contextmenu禁止鼠标右键菜单
selectstart禁止鼠标选中
<p>我是一条程序指令</p>
<script>
var p = document.querySelector("p");
p.addEventListener("contextmenu", function (e) {
e.preventDefault(); //取消鼠标右键
});
p.addEventListener("selectstart", function (e) {
e.preventDefault(); //取消鼠标选中
});
</script>
5、鼠标事件对象位置属性
鼠标事件对象位置属性 | 说明 |
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标,IE9+支持 |
e.pageY | 返回鼠标相对于文档页面的Y坐标,IE9+支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
/* 鼠标相对于浏览器可视区的坐标 */
document.addEventListener("click", function (e) {
console.log("e.clientX: " + e.clientX);
console.log("e.clientY: " + e.clientY);
console.log("e.pageX: " + e.pageX);
console.log("e.pageY: " + e.pageY);
console.log("e.screenX: " + e.screenX);
console.log("e.screenY: " + e.screenY);
});
案例:
图片跟随鼠标的移动
//需要定位
<style>
img {
position: absolute;
width: 100px;
}
</style>
<img src="../images/4.webp" alt="" />
<script>
var img = document.querySelector("img");
document.addEventListener("mousemove", function (e) {
img.style.top = e.pageY + "px";
img.style.left = e.pageX + "px";
img.style.transform = "translate(-50%,-50%)";
img.style.cursor = "none";
});
</script>
6、键盘事件
键盘事件
onkeyup 键盘按下又回弹触发事件,不区分大小写,尽量使用keyCode来获取ASCLL码值
onkeydown 键盘按下触发事件,不区分大小写
onkeypress 键盘按下触发事件,但是不是识别功能键,区分大小写
keypres识别大小写是根据keyCode属性识别的
keyup和keudown中的keyCode属性不能识别大小写,ASCLL码值一样的
三个的执行顺序是 keydown keypress keyup
// keyup和keydown键盘事件不能识别大小写
document.addEventListener("keyup", function (e) {
console.log(e.keyCode);
});
// 练习利用keyCode属性识别按键大小写
document.addEventListener("keypress", function (e) {
if (e.keyCode >= 65 && e.keyCode <= 90) {
console.log(e.key + "\t" + e.keyCode);
console.log("你输入的是大写");
} else {
console.log("你输入的可能是小写");
console.log(e.key + "\t" + e.keyCode);
}
});
7、BOM_窗口加载事件(load DOMContentLoad)
窗口加载事件onload
注意点:如果是加载事件,可以将js代码放在元素前面(因为onload事件是页面加载完毕之后才执行的js代码)
如果不是加载事件,如果使用事件委托形式,也可以放在元素前面
如果要获取元素先,则此时需要放在元素后面
window.addEventListener('load', function () {
window.alert('我是别的内容加载完成后执行的事件');
})
窗口加载事件
window.onload = function(){}
window.addEventListener('load',function(){})
window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件
(包括图像、脚本文件、css文件等数据),就调用的处理函数
注意:
1、有了window.onload就可以把js代码写在页面中标签元素的上方或者是下方,因为onload是等页面标签元素全部加载完毕之后才执行处理函数
2、window.onload传统注册事件的方式,只能写一次,如果存在多个,会以最后一个window.onload事件为准
3、如果需要写多个onload事件,使用addEventListener()注册事件的方式,没有次数限制
窗口加载事件
document.addEventListener('DOMContentLoad',function(){})
1、DOMContentLoad事件触发时,仅当DOM(文档对象模型,就是标签元素)加载完毕,不包括样式表、图片、falsh等
2、ie9以上版本才支持
3、如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoad时间比较合适使用
8、BOM_调整窗口大小事件
调整窗口大小的事件onresize:调整窗口的大小的事件
window.onresize=function(){}
window.addEventListener('resize',function(){})
window.onresize是调整窗口大小加载事件,当触发时就会调用的处理函数
注意:
只要窗口的大小发生像素变化,就会触发这个事件
经常利用这个事件完成响应式布局,window.innerWidth来获取当前屏幕的宽度
<script>
window.onresize = function () {
console.log("我变化了");
console.log(window.innerWidth); //获取当前电脑屏幕的宽度
};
</script>
9、定时器
setTimeout()/setInterval()定时器
window.setTimeout(callback,延迟的毫秒数,传递给回调的参数);
setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数
注意:
1、window可以省略
2、这个调用函数可以直接写成函数,或者写函数名或者采取字符串形式'函数名()'三种形式,第三种不推荐使用
3、延迟的毫秒数省略默认是0,如果写,必须是毫秒
4、因为定时器可能有多个,所以经常给定时器一个标识符
setInterval()定时器
window.setInterval(callback,毫秒数)
setInterval()方法重复调用一个函数,每到这个时间,就调用一次函数
注意点和setTimeout()的一样
// 停止setTimeout()定时器
window.clearTimeout(timeoutID)
// 停止setInterval()定时器
window.clearInterval(timeoutID)
// 如:
let timer = window.setTimeout(callback,毫秒数);
window.document.addEventListener('click'.function(){
window.clearTimeout(timer);
})
练习:
<button>点击</button>
<script>
let timer = undefined;
document.querySelector("button").onclick = function () {
clearInterval(timer);
timer = setInterval(
(params) => {
console.log(params);//{ a: 100, b: 200 }
},
1000,
{ a: 100, b: 200 }
);
};
</script>
10、按钮的disabled 属性
disabled 属性为真表示可以禁止点击,为false表示可以点击
<button>点击</button>
<script>
const button = document.querySelector("button");
button.onclick = function () {
this.disabled = true;
this.style.cursor = "move";
setTimeout(() => {
this.disabled = false;
this.style.cursor = "default";
}, 3000);
};
</script>
验证码案例:
<input type="text" />
<button>发送验证码</button>
<script>
const button = document.querySelector("button");
const input = document.querySelector("input");
let timer = undefined;
let count = 3;
button.onclick = function () {
this.disabled = true;
timer = setInterval(() => {
count--;
button.textContent = "请等待" + count + "秒";
if (!count) {
clearInterval(timer);
this.disabled = false;
button.textContent = "发送验证码";
input.value = "1234";
count = 3;
}
}, 1000);
};
</script>
11、window中this的指向的问题
这里是我自己的理解,如果有更好的说明,欢迎评论:
1、全局下function函数的调用后this的指向都是window
2、在全局下打印的this也是指向window
3、对象中,如果在对象的内部调用函数,普通函数的this指向的是对象
4、箭头函数中,this指向的是最近的一层具有完整function关键字的且调用了完整function关键字的对象
<button>点击</button>
<script>
// 1、全局下调用的函数
function func() {
console.log(this, "func函数中的"); //window
}
func();
// 定时器的箭头函数
const button = document.querySelector("button");
button.onclick = function () {
setTimeout(() => {
console.log(this, "这里是button点击事件中的"); //button
}, 0);
};
// 全局下直接输出的this
console.log(this, "全局下的"); //window
// 普通对象上的箭头函数
var obj = {
name: "张三",
sayHello() { // 这里的完成写法是 sayHello:function(){}
let obj1 = {
play: () => {
console.log(this, "obj中的"); //obj
},
};
obj1.play();
},
};
obj.sayHello();
// 构造函数中的this
function People(name, age) {
this.name = name;
this.age = age;
this.sayHi = function () {
console.log(this);//People
};
}
var peo = new People("张三", 20);
peo.sayHi();
</script>
12、JS中同异步任务和执行机制
js是单线程
js语言的一大特点就是单线程执行,也就是说同一个时间点只能做一件事。这是因为js这门脚本语言诞生的使命所在,js是为了处理页面中用户的交互以及操作DOM而诞生的。某个DOM元素进行添加和删除操作,不能同时进行,先添加才能删除单线程意味着所有任务需要排队,前一个任务结束够才会执行下一个任务,这样导致如果js执行的时间过长,就会造成页面的渲染不连贯的问题导致页面加载阻塞。
同步和异步
为了解决页面渲染出现的阻塞问题,利用多核CPU计算能力,h5提出web worker标准,允许js脚本创建多个线程。于是js中出现了同步和异步任务。
同步:前一个任务执行结束,程序按照顺序执行下一个任务。
异步:同一个时间内可以做多件事
同步任务:都在主线程上执行,形成一个执行栈
异步任务:普通事件(click、resize等) 资源加载(load、error等) 定时器,包括setTimeout、setInterval等
js执行机制
1、先执行执行栈中的同步任务
2、异步任务(回调函数)放入任务队列中
3、一旦执行栈中的所有同步任务执行完毕之后,系统就会按照次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进行执行栈中开始执行。由于主线程不断的重复获取任务、执行任务、再获取任务,所以这种机制被称为是事件循环(event loop)
13、history对象
history 对象是浏览器提供的内置对象之一,它提供了与浏览器历史记录相关的功能。
通过 history 对象,您可以在浏览器窗口的会话历史记录中导航、管理浏览历史记录以及在不同页面之间进行前进和后退操作。
history.back():导航到上一个页面(相当于点击浏览器的后退按钮)。
history.forward():导航到下一个页面(相当于点击浏览器的前进按钮)。
history.go(n):在历史记录中导航到相对于当前页面的某个位置,其中 n 可以是正数(向前导航)或负数(向后导航)。
// history后退.html文件
<a href="./history前进.html">history后退</a>
<button>后退</button>
<script>
var button = document.querySelector('button');
button.addEventListener('click', function () {
// history.back();
history.go(-1);
})
</script>
// history前进.html文件
<a href="./history后退.html">history前进</a>
<button>前进</button>
<script>
var button = document.querySelector('button');
button.addEventListener('click', function () {
// history.forward();
history.go(1);
})
</script>
14、location对象
window对象给我们提供的一个location属性用来获取或设置窗体的URL,并且可以用于解析URL,
因为这个属性返回的是一个对象,所以我们将这个属性也成为location对象
console.log(window.location.href); //获取href(整个文件的地址)
URL:统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址,
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
URL的一般语法格式:
protocol://host[:post]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
组成 说明
protocol 通信协议,常用的http,ftp,maito等
host 主机(域名),例如:www.itcast.cn
port 端口号,可选,如果省略,http默认的端口是80
path 路径,由零个或多个/符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
query 参数,以键值对的形式,通过&符号分割开
fragment 片段,#后面内容常见用于链接,锚点
location的属性:
location的属性 返回值
location.href 获取或者设置吻技安的整个URL
location.host 返回主机或者域名
location.port 返回端口号,如果未写端口号,返回空字符串
location.pathname 返回路径
location.search 返回参数
location.hash 返沪片段,#后面内容,常见于链接,锚点
location对象的方法:
location.assign() 跟href一样,可以跳转页面(也称为重定向页面),点击跳转之后还可以后退到之前的页面
location.replace() 替换当前页面,因为不记录历史,所以不能后退到之前的页面
location.reload() 重新加载页面,相当于刷新按钮或者f5键,如果参数是空,或者是false, 就只是单纯的刷新的意思,如果参数是true, 就是强制刷新的意思(ctrl_f5)
<script>
window.addEventListener("click", function () {
// location.assign('http://baidu.com')//跳转,有后退功能
location.replace("http://baidu.com"); //跳转,没有后退功能
// location.reload()//加载页面,不跳转
});
</script>
15、navigator对象
navigator对象包含有关浏览器的信息,有很多属性,最常用的属性是userAgent, 该属性可以返回由客户机
发送到服务器的user - agent头部的值
下面前端代码可以解决判断用户哪个终端打开页面,实现跳转
if (navigator.userAgent.match( /(phone|pad|pod|iphone|ipod|ios|ipad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Sybian|Windows Phone)/i)) {
location.href = "#";// 移动端
} else {
location.href = "#";// 客户端
}
16、PC端网页特效_offset偏移量
概述:offset翻译就是偏移量,使用offset相关属性可以动态的得到元素属性,
比如:位置(偏移),大小等获得元素距离带有定位父元素的位置,获得元素自身的大小(宽度和高度)
注意:返回的数值都不带单位
offset系列常见的属性:
属性 作用
element.offsetParent 返回作为该元素带有定位的父元素,如果父级没有带定位,则结果返回是body
element.offsetTop 返回元素相对于带有定位的父元素上方的偏移量
element.offsetLeft 返回元素相对于带有定位的父元素左边框的偏移量
element.offsetWidth 返回自身包括padding 边框 内容去的宽度,返回的数值不带有单位
element.offsetHeight 返回自身包括padding 边框 内容去的高度,返回的数值不带有单位
<div></div>
<script>
var div = document.querySelector("div");
console.log(div.offsetParent);
console.log(div.offsetHeight);
console.log(div.offsetWidth);
console.log(div.offsetTop);
console.log(div.offsetLeft);
</script>
17、offset和style的区别
offset和style的区别:
offset
offset可以得到任意样式表的样式值
offset系列获得的数值是没有带单位的
offsetWidth包含padding 边框 内容去的宽度
offsetWidth等属性是只读属性,只能获取不能赋值,也改变不了
所以想要获取元素大小,位置等属性,使用offset比较适合
style
style只能得到行内样式表的样式值(就是直接定义在标签中的样式)
style.width获得的是带有单位的字符串
style.width获得不包含padding 和 border 的值
style.width是可读写属性,可以获取也可以改变
所以想要给改变元素属性的值,使用style
<div
style="
position: absolute;
top: 100px;
left: 100px;
width: 200px;
height: 200px;
border: 10px solid red;
padding: 50px;
background-color: pink;
margin: 100px auto;
"
></div>
<script>
var div = document.querySelector("div");
console.log(div.offsetHeight);
console.log(div.offsetWidth);
// 因为offset输出的结果中有包含padding border 的值,所以结果相比style要大
console.log(div.offsetTop);
console.log(div.offsetLeft);
console.log("_________________");
// style输出的结果中没有包含padding border 的值
console.log(div.style.height);
console.log(div.style.width);
// 如果行内样式表中没有定义的属性,输出是为空
console.log(div.style.top);
console.log(div.style.left);
console.log(div.style.backgroundColor);
div.style.backgroundColor = "red";
console.log(div.style.backgroundColor);
</script>
案例:
<div
style="
position: absolute;
top: 100px;
left: 100px;
width: 100px;
height: 100px;
background-color: red;
"
></div>
<script>
var div = document.querySelector("div");
window.addEventListener("click", function (e) {
console.log("鼠标点击模块中的坐标是");
console.log(e.pageX - div.offsetLeft);
console.log(e.pageY - div.offsetTop);
});
</script>
案例:
<!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>
</head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h2 {
text-align: center;
cursor: pointer;
}
.bg {
display: none;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.3);
}
form {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 240px;
border-radius: 5px;
background-color: #fff;
padding: 30px 30px;
cursor: default;
}
form .close {
position: absolute;
width: 40px;
height: 36px;
line-height: 36px;
text-align: center;
border-radius: 50%;
outline: none;
border: 0;
top: -18px;
right: -20px;
}
form .top {
font-size: 20px;
font-weight: 500;
text-align: center;
}
form label {
display: block;
text-align: right;
}
form label input {
outline: none;
border: 1px solid #999;
width: 260px;
height: 36px;
margin-top: 20px;
border-radius: 5px;
color: #999;
padding-left: 20px;
}
form .login {
display: block;
width: 200px;
height: 30px;
color: #000;
font-weight: 500;
outline: none;
border: 1px solid #999;
border-radius: 5px;
margin: 20px auto;
background-color: #fff;
}
</style>
<body>
<h2>点击,弹出模态框</h2>
<div class="bg">
<form action="#" class="input_box">
<button class="close">关闭</button>
<div class="top">登录会员</div>
<label
>用户名:<input type="text" name="user" placeholder="请输入你的账号"
/></label>
<label
>登录密码:<input
type="password"
name="pwd"
placeholder="请输入你的密码"
/></label>
<button class="login">登录会员</button>
</form>
</div>
<script>
const h2 = document.querySelector("h2");
const bg = document.querySelector(".bg");
const close = document.querySelector(".close");
const form = document.querySelector("form");
h2.addEventListener("click", function () {
bg.style.display = "block";
form.style.display = "block";
close.addEventListener("click", function () {
form.style.display = "none";
bg.style.display = "none";
});
form.addEventListener("mousedown", function (e1) {
this.style.cursor = "move";
const click_x = e1.pageX - this.offsetLeft;
const click_y = e1.pageY - this.offsetTop;
document.addEventListener("mousemove", move);
function move(e2) {
form.style.top = e2.pageY - click_y + "px";
form.style.left = e2.pageX - click_x + "px";
}
document.addEventListener("mouseup", function () {
this.removeEventListener("mousemove", move);
});
});
});
</script>
</body>
</html>
18、三大系列_scrollWidth_offsetWidth_clientWidth
element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回值不带单位
element.clientWidth 返回自身包括padding、内容区的宽度,不包括边框,返回值不带单位
element.scrollWidth 返回自身内容区的宽度,不包括padding和边框,返回值不带单位
补充:
Element.scrollWidth 这个只读属性是元素内容宽度的一种度量,包括由于 overflow 溢出而在屏幕上不可见的内容。
<style>
div {
width: 140px;
height: 140px;
background-color: pink;
border: 10px solid red;
padding: 10px;
}
</style>
<div></div>
<script>
window.addEventListener("load", function () {
var div = document.querySelector("div");
console.log(div.offsetWidth); //160 width padding border-width
console.log(div.clientWidth); //140 width padding
console.log(div.scrollWidth); //140
// 如果元素的内容可以适合而不需要水平滚动条,则其scrollWidth等于clientWidth
});
</script>
19、PC端网页特效_scroll属性
scoll翻译就是滚动,使用scoll系列的相关属性可以动态的得到该元素的大小、滚动距离等
scoll系列属性 作用
element.scollTop 返回被卷去的上侧距离,返回数值不带单位
element.scollLeft 返回被卷去的左侧距离,返回数值不带单位
element.scollWidth 返回自身实际的宽度,不含边框,返回数值不带单位
element.scollHeight 返回自身实际的高度,不含边框,返回数值不带单位
案例分析:
需要用到页面滚动事件scroll因为是页面滚动,所以事件源是document
滚动到某个位置,就是判断页面被卷去的上部值
页面被卷去的头部:可以通过window.pageYOffset获得,如果是被卷去的左侧window.pageXOffset
注意:元素被卷去的头部是element.scrollTop,如果是页面被卷去的头部则是window.pageYOffset
页面被卷去的头部兼容性问题解决方案 :
需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常由如下几种写法:
1、声明了DTD: 使用document.documentElement.scrollTop
2、未声明DTD: 使用document.body.scrollTop
3、新方法DTD: 使用window.pageYOffset,ie9开始支持
上下移动的导航栏
<!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>
</head>
<body>
<div class="div">
<div class="header w">header</div>
<div class="banner w">banner</div>
<div class="main w">main</div>
</div>
<div class="slider-bar">
<div class="goback">返回</div>
</div>
<script>
window.addEventListener("load", function () {
const sbar = document.querySelector(".slider-bar");
document.addEventListener("scroll", function () {
if (window.pageYOffset >= 200) {
sbar.style.display = "block";
sbar.style.position = "fixed";
} else {
sbar.style.display = "none";
}
});
sbar.addEventListener("click", function () {
animate(window, 0);
function animate(object, targetlocation, callback) {
fun();
clearInterval(object.timer);
object.timer = setInterval(fun, 10);
function fun() {
let step = (targetlocation - window.pageYOffset) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
window.scroll(0, window.pageYOffset + step);
if (step == 0) {
clearInterval(object.timer);
callback && callback();
}
}
}
});
});
</script>
</body>
<style>
.div {
width: 80%;
position: absolute;
top: 0;
}
.header {
background-color: pink;
}
.banner {
background-color: red;
}
.main {
background-color: skyblue;
}
.w {
width: 100%;
height: 400px;
text-align: center;
line-height: 400px;
margin-top: 20px;
}
.slider-bar {
position: absolute;
top: 300px;
right: 100px;
display: none;
}
.goback {
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
background-color: lightgreen;
}
</style>
</html>
左右移动的导航栏
<!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>
</head>
<body>
<div class="box">
<div class="div">我是左右移动栏</div>
<span>--></span>
</div>
<script>
var span = document.querySelector("span");
var div = document.querySelector(".div");
span.addEventListener("mouseenter", function () {
animate(div, -160, function () {
span.innerHTML = "-->";
});
});
span.addEventListener("mouseout", function () {
animate(div, 0, function () {
span.innerHTML = "<--";
});
});
function animate(object, targetLocation, callback) {
clearInterval(object.timer);
fun();
object.timer = setInterval(fun, 20);
function fun() {
let step = (targetLocation - object.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
object.style.left = object.offsetLeft + step + "px";
if (step == 0) {
clearInterval(object.timer);
callback && callback();
}
}
}
</script>
</body>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.box {
position: absolute;
right: 40px;
top: 300px;
}
span {
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 40px;
height: 40px;
background-color: pink;
text-align: center;
line-height: 40px;
color: #000;
}
.div {
position: absolute;
top: 0;
left: 0;
font-size: 10px;
width: 200px;
height: 40px;
background-color: red;
text-align: center;
line-height: 40px;
}
</style>
</html>
19、bootstrap轮播图
JavaScript 插件 · Bootstrap v3 中文文档 | Bootstrap 中文网
20、自定义的轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
.box,
.child,
.fa-box,
ul,
li {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.fa-box {
width: 400px;
height: 300px;
background-color: red;
position: absolute;
top: 100px;
left: 50%;
transform: translateX(-50%);
overflow: hidden;
}
.box {
position: absolute;
top: 0;
left: 0;
display: flex;
}
.child {
width: 400px;
height: 300px;
float: left;
}
.first {
background-color: pink;
}
.second {
background-color: skyblue;
}
.third {
background-color: lightgreen;
}
.pot {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
}
li {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #fff;
list-style: none;
margin: 0 5px;
}
.active {
background-color: #999;
}
button {
outline: none;
border: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 40px;
background-color: transparent;
color: #fff;
font-size: 20px;
}
button:hover {
background-color: rgba(0, 0, 0, 0.3);
}
.left {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
left: 0;
}
.right {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
right: 0;
}
</style>
<body>
<div class="fa-box">
<div class="box">
<div class="child first"></div>
<div class="child second"></div>
<div class="child third"></div>
</div>
<ul class="pot"></ul>
<button class="left">></button>
<button class="right"><</button>
</div>
<script>
const child = document.querySelectorAll(".child");
const ul = document.querySelector(".pot");
const box = document.querySelector(".box");
const faBox = document.querySelector(".fa-box");
// 动态生成小点
for (let i = 0; i < child.length; i++) {
const li = document.createElement("li");
ul.appendChild(li);
li.setAttribute("data-index", i + 1);
}
const li = document.querySelectorAll("li");
li[0].classList.add("active");
// 一开始就开启定时器
Window.timer = setInterval(() => {
button[0].click();
}, 1000);
// 给每个小点绑定点击事件
for (let i = 0; i < li.length; i++) {
li[i].addEventListener("click", function () {
index = this.getAttribute("data-index") - 1;
liIndex = index;
console.log(index);
for (let i = 0; i < li.length; i++) {
li[i].classList.remove("active");
}
li[liIndex].classList.add("active");
animate(box, -faBox.offsetWidth * index);
});
}
// 克隆第一张图片
const first = box.children[0].cloneNode(true);
box.appendChild(first);
first.setAttribute(
"data-index",
box.children[0].getAttribute("data-index")
);
const button = document.querySelectorAll("button");
// 切换图片的index
let index = 0;
// 切换小点的liIndex
let liIndex = 0;
// 点击左按钮切换
button[0].addEventListener("click", function () {
// 当切换到最后一张,立刻切换到第一张,这里不使用动画
if (index == child.length) {
index = 0;
box.style.left = "0px";
}
index++;
liIndex++;
// 判断当小点达到最后一个时切换到第一个
if (liIndex == li.length) {
liIndex = 0;
}
// 排他思想渲染小点样式
for (let i = 0; i < li.length; i++) {
li[i].classList.remove("active");
}
li[liIndex].classList.add("active");
// 动画函数,动画切换
animate(box, -index * faBox.offsetWidth);
});
// 点击右按钮切换图片
button[1].addEventListener("click", function () {
// 当切换到第一张时,立刻切换到最后一张
if (index == 0) {
index = child.length;
box.style.left = -index * faBox.offsetWidth + "px";
}
index--;
liIndex--;
if (liIndex < 0) {
liIndex = 2;
}
for (let i = 0; i < li.length; i++) {
li[i].classList.remove("active");
}
li[liIndex].classList.add("active");
animate(box, -index * faBox.offsetWidth);
});
// 鼠标进入faBox时,使用事件委托,触发faBox的mouseover来停止定时器
faBox.addEventListener("mouseover", function () {
// 停止定时器执行
clearInterval(Window.timer);
// 标记定时器为停止
Window.timer = null;
// 鼠标离开重新开启定时器
faBox.addEventListener("mouseout", function () {
// 先清除一次再开启,避免多次开启定时器
clearInterval(Window.timer);
Window.timer = null;
Window.timer = setInterval(() => {
button[0].click();
}, 1000);
});
});
// 封装的动画函数,使图片切换更柔和
function animate(object, targetLocation, callback) {
clearInterval(object.timer);
fun();
object.timer = setInterval(fun, 10);
function fun() {
let step = (targetLocation - object.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
object.style.left = object.offsetLeft + step + "px";
if (step == 0) {
clearInterval(object.timer);
callback && callback();
}
}
}
</script>
</body>
</html>
后续前往CSDN