JS学习-8.9日学习内容
仿淘宝放大镜案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
</title>
<style>
.box{
width:400px;
height: 400px;
border: 1px solid #5085FF;
position: relative;
}
.img1{
width:90%;
height:90%;
position: relative;
left:5%;
top: 5%;
}
.img2{
position: absolute;
left:0;
top: 0;
}
.big{
width: 500px;
height: 500px;
border: 1px solid #aca79d;
position: absolute;
left: 420px;
top:0;
display: none;
overflow: hidden;
}
.mask{
display: none;
width: 200px;
height: 200px;
background-color: coral;
position: absolute;
top:0;
left: 0;
opacity: .5;
cursor: move;
}
</style>
</head>
<body>
<div class="box">
<img class="img1" src="https://img.alicdn.com/imgextra/i1/TB1Ba7fXKkJL1JjSZFmYXIw0XXa_M2.SS2_430x430q90.jpg" />
<div class="mask"></div>
</div>
<div class="big">
<img class="img2" src="https://img.alicdn.com/imgextra/i1/TB1Ba7fXKkJL1JjSZFmYXIw0XXa_M2.SS2 "/>
</div>
<script>
var mask=document.querySelector('.mask');
var big=document.querySelector('.big');
var box=document.querySelector('.box');
box.addEventListener('mouseover',function(){
mask.style.display='block';
big.style.display='block';
})
box.addEventListener('mouseout',function(){
mask.style.display='none';
big.style.display='none';
})
box.addEventListener('mousemove',function(e){
var x=e.pageX-box.offsetLeft;
var y=e.pageY-box.offsetTop;
var maskx=x-mask.offsetWidth/2;
var masky=y-mask.offsetHeight/2;
var maskMax=box.offsetWidth-mask.offsetWidth;
if(maskx<=0)
maskx=0;
else if(maskx >= maskMax)
maskx=maskMax;
if(masky<=0)
masky=0;
else if(masky >= maskMax)
masky=maskMax;
mask.style.left=maskx+'px';
mask.style.top=masky+'px';
//大图片的移动距离=遮挡层移动距离*大图片的最大移动距离/遮挡层的最大移动距离
var img2=document.querySelector('.img2');
//大图片的最大移动距离
var bigMax=img2.offsetWidth-big.offsetWidth;
//大图片的移动距离X Y
var bigx=maskx*bigMax/maskMax;
var bigy=masky*bigMax/maskMax;
img2.style.left=-bigx+'px';
img2.style.top=-bigy+'px';
})
</script>
</body>
</html>
元素可视区 client系列
client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
client系列属性 | 作用 |
---|---|
element.clientTop | 返回元素上边框的大小 |
element.clientLeft | 返回元素左边框的大小 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |
element.clientHeight | 返回自身包括padding、内容区的高度,不含边框,返回数值不带单位 |
client与offset的区别是不包含边框。
立即执行函数
立即执行,不需要调用,可以自己执行的函数,最大的作用就是独立创建了一个独立作用域,避免了命名冲突问题。
写法:(function(){})()
或者(function(){}())
//(function(){})()
(function(a, b) {
console.1og(a + b);
})(1, 2); //第二个小括号可以看做是调用函数
//(function(){}())
(function sum(a, b) {
console.1og(a + b);
}(2, 3));
pageshow事件
pageshow事件在页面显示时触发, 无论页面是否来自缓存。在重新加载页面中, pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件给window添加。
元素滚动scroll系列
scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等。
scroll系列属性 | 作用 |
---|---|
element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |
element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
页面被卷去的头部:可以通过window.pageYOffset
获得如果是 被卷去的左侧window.pageXOffset
。
注意:元素被卷去的头部是element.scrollTop
,如果是页面被卷去的头部则是window.pageYOffset
。
仿淘宝固定侧边栏案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.header{
width: 90%;
height: 200px;
background-color: #5085FF;
margin: 5px;
}
.banner{
width: 90%;
height: 500px;
background-color: #e3ff85;
margin: 5px;
}
.main{
width: 90%;
height: 1000px;
background-color: #ff792b;
margin: 5px;
}
span{
position: absolute;
display: none;
}
.slider-bar{
position: absolute;
width: 100px;
height: 100px;
background-color: #DB7093;
left:90%;
top:300px;
}
</style>
</head>
<body>
<div class="slider-bar">
<span class="goBack">返回顶部</span>
</div>
<div class="header">头部区域</div>
<div class="banner">banner取悦</div>
<div class="main">主体部分</div>
<script>
var slider=document.querySelector('.slider-bar');
var banner=document.querySelector('.banner');
var goBack=document.querySelector('.goBack');
var main=document.querySelector('.main');
var mainTop=main.offsetTop;
var bannerTop=banner.offsetTop;
//侧边栏固定定位后应该变化的值
var sliderTop=slider.offsetTop-banner.offsetTop;
document.addEventListener('scroll',function(){
if(window.pageYOffset>=bannerTop) {
slider.style.position='fixed';
slider.style.top=sliderTop+'px';
}
else{
slider.style.position='absolute';
slider.style.top=300+'px';
}
if(window.pageYOffset>=mainTop){
goBack.style.display='block';
}
else{
goBack.style.display='none';
}
})
</script>
</body>
</html>
需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:
1.声明了DTD ,使用document . documentElement . scrollTop
2.未声明DTD ,使用document .body. scrollTop
3.新方法window . pageYOffset
和window . pageXOffset
, IE9开始支持
解决方法:
function getscrol1() {
return {
left: window.pageXOffset||document. documentElement.scrollLeft || document.body. scrollLeft||0,top: window. pageYOffset|| document.documentElement.scrolTop||document. body.scrollToP||0
};
}
//使用的时候getscroll().1eft
三大系列总结
三大系列大小对比 | 作用 |
---|---|
element.offsetWidth | 返回自身包括padding,边框,内容区的宽度,返回数值不带单位 |
element.clientWidth | 返回自身包括padding,内容区的宽度,不包含边框,返回数值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
主要用法:
- offset系列 经常用于获得元素位置offsetLeft offsetTop
- client 经常用于获取元素大小clientWidth clientHeight
- scroll经常用于获取滚动距离 scrollTrop scrolleft
- 注意页面滚动的距离通过window. pagexoffset获得
mouseenter和mouseover的区别
●当鼠标移动到元素上时就会触发mouseenter事件
●类似mouseover ,它们两者之间的差别是
●mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发
●之所以这样,就是因为mouseenter不会冒泡
动画函数封装
动画原理
1.获得盒子当前位置
2.让盒子在当前位置加上1个移动距离
3.利用定时器不断重复这个操作
4.加一个结束定时器的条件
5.注意此元素需要添加定位,才能使用element . style. left
移动盒子案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width:100px;
height:100px;
background-color: #DB7093;
position: absolute;
left: 10px;
}
</style>
</head>
<body>
<div></div>
<script>
var div=document.querySelector('div');
var timer=setInterval(function(){
if(div.offsetLeft>=500){
clearInterval(timer);
} div.style.left=div.offsetLeft+10+"px";
},30)
</script>
</body>
</html>
封装动画函数:
//简单动画函数封装obj目标,target目标位置
function animate(obj,target){
//先清除以前的定时器,只保留当前的一个定时器
clearInterval(obj.timer);
obj.timer=setInterval(function(){
if(obj.offsetLeft==target){
clearInterval(obj.timer);
}
obj.style.left=obj.offsetLeft+10+"px";
},30)
}
缓动效果
1.让盒子每次移动的距离慢慢变小,速度就会慢慢落下来。
2.核心算法: (目标值-现在的位置) / 10 做为每次移动的距离步长。
3.停止的条件是:让当前盒子位置等于目标位置就停止定时器。
//简单动画函数封装obj目标,target目标位置
function animate(obj,target){
//先清除以前的定时器,只保留当前的一个定时器
clearInterval(obj.timer);
obj.timer=setInterval(function(){
if(obj.offsetLeft==target){
clearInterval(obj.timer);
}
var pace=(target-obj.offsetLeft)/10;
pace=pace>0?Math.ceil((target-obj.offsetLeft)/10):Math.floor((target-obj.offsetLeft)/10);
obj.style.left=obj.offsetLeft+pace+"px";
},15)
}
动画函数添加回调函数
回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另-个函数里面,当那个函数执行完之后再执行传进去的这个函数,这个过程就叫做回调。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width:100px;
height:100px;
background-color: #DB7093;
position: absolute;
left: 10px;
}
</style>
</head>
<body>
<div></div>
<script>
//简单动画函数封装obj目标,target目标位置
function animate(obj,target,callback){
//先清除以前的定时器,只保留当前的一个定时器
clearInterval(obj.timer);
obj.timer=setInterval(function(){
if(obj.offsetLeft==target){
clearInterval(obj.timer);
if(callback){
callback();
}
}
var pace=(target-obj.offsetLeft)/10;
pace=pace>0?Math.ceil((target-obj.offsetLeft)/10):Math.floor((target-obj.offsetLeft)/10);
obj.style.left=obj.offsetLeft+pace+"px";
},15)
}
var div=document.querySelector('div');
animate(div,600,function(){
div.style.backgroundColor='red';
});
</script>
</body>
</html>
弹出栏案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.sliderbar{
position: absolute;
left:50%;
top:50%;
width: 40px;
height: 30px;
}
span{
width: 50px;
height: 50px;
background-color:#FF0000;
}
.con{
width: 100px;
height: 30px;
background-color: #FF0000;
border-radius: 2px;
color:#FFF;
position: relative;
top:-30px;
left: 20px;
/* display: none; */
}
</style>
<script src="animate.js"></script>
</head>
<body>
<div class="sliderbar">
<span>←</span>
<div class="con">问题反馈</div>
</div>
<script>
var sp=document.querySelector('span');
var con=document.querySelector('.con');
var slliderbar=document.querySelector('.sliderbar');
slliderbar.addEventListener('mouseenter',function(){
animate(con,-100,function(){
sp.innerHTML='→';
});
})
slliderbar.addEventListener('mouseleave',function(){
animate(con,17,function(){
sp.innerHTML='←';
});
})
</script>
</body>
</html>
JS轮播图案例
轮播图.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link type="text/css" rel="styleSheet" href="index.css" />
<script src="轮播图.js"></script>
<script src="animate.js"></script>
</head>
<body>
<div class="w">
<div class="main">
<div class="focus ">
<a href="javascript:;" class="arrow-1">
<
</a>
<a href="javascript:;" class="arrow-r">
>
</a>
<ul class="imgs">
<li>
<a href="#"><img src="https://img.alicdn.com/tfs/TB1tm6JQaL7gK0jSZFBXXXZZpXa-520-280.jpg" ></a>
</li>
<li>
<a href="#"><img src="https://img.alicdn.com/simba/img/TB1HtDMFHj1gK0jSZFuSuwrHpXa.jpg" ></a>
</li>
<li>
<a href="#"><img src="https://gw.alicdn.com/tfs/TB1GPVEeggP7K4jSZFqXXamhVXa-520-280.jpg" ></a>
</li>
<li>
<a href="#"><img src="https://img.alicdn.com/simba/img/TB1sN5zMVY7gK0jSZKzSuuikpXa.jpg" ></a>
</li>
</ul>
<ol class="current">
</ol>
</div>
</div>
</div>
</body>
</html>
index.css:
.focus{
width:520px;
height: 280px;
position: relative;
/* left: 400px;
top:100px; */
background-color: #5085FF;
overflow: hidden;
}
.focus ul{
width: 500%;
position: absolute;
left:0 ;
top:0;
}
img{
width: 100%;
height: 100%;
position: relative;
left:-30px;
top:19px;
}
.focus ul li{
float: left;
}
.imgs li{
list-style-type: none;
position: relative;
left: -10px;
top: -35px;
}
.arrow-1{
display: none;
position: absolute;
top: 50%;
margin-top: - 20px;
width: 24px ;
height: 40px;
background: rgba(0, 0, 0, .3);
text-align: center;
line -height: 40px;
color: #fff ;
font-family: ' icomoon';
font-size: 18px;
z-index: 1;
}
.arrow-r{
display: none;
position: absolute;
top: 50%;
left: 95%;
margin-top: - 20px;
width: 24px ;
height: 40px;
background: rgba(0, 0, 0, .3);
text-align: center;
line -height: 40px;
color: #fff ;
font-family: ' icomoon';
font-size: 18px;
z-index: 1;
}
a{
text-decoration: none;
}
.circle{
color: #FFFFFF;
font-size: 30px;
float: left;
margin:10px;
position: relative;
top: 200px;
}
.click_circle{
color: #ff6c03;
font-size: 30px;
float: left;
margin:10px;
position: relative;
top: 200px;
}
轮播图.js:
window.addEventListener('load',function(){
var arrow_l=document.querySelector('.arrow-1');
var arrow_r=document.querySelector('.arrow-r');
var focus=document.querySelector('.focus');
var ol=focus.querySelector('.current');
var focusWith=focus.offsetWidth;
var flag=true;
focus.addEventListener('mouseenter',function(){
arrow_l.style.display='block';
arrow_r.style.display='block';
clearInterval(timer);
timer=null;//释放空间
})
focus.addEventListener('mouseleave',function(){
arrow_l.style.display='none';
arrow_r.style.display='none';
timer=setInterval(function(){
arrow_r.click();
},1000);
})
var ul=focus.querySelector('ul');
//创建小li
for(var i=0;i<ul.children.length;i++){
var li=document.createElement('li');
li.setAttribute('index',i);//自定义属性索引号
//小li插入到ol后
ol.appendChild(li);
//给小li样式
ol.children[i].type='disc';
ol.children[i].className='circle';
li.addEventListener('click',function(){
//添加样式li
for(var i=0;i<ol.children.length;i++)
ol.children[i].className='circle';
this.className='click_circle';
//点击小圆圈,移动图片
var index=this.getAttribute('index');
//当我们点击了某个小li就要把这个li的索引号给num
num=index;
//当我们点击了某个小li就要把这个li的索引号给ci
ci=index;
animate(ul,-index*focusWith);
})
}
ol.children[0].className='click_circle';
var first=ul.children[0].cloneNode(true);
ul.appendChild(first);
var num=0;
var ci=0;
//右侧按钮
arrow_r.addEventListener('click',function(){
if(flag){//节流阀
flag=false;
if(num==ul.children.length-1)
num=0;
num++;
animate(ul,-num*focusWith,function(){
flag=true;
});
//点击按钮后小圆圈跟随一起变化
ci++;
if(ci==ol.children.length)
ci=0;
for(var i=0;i<ol.children.length;i++)
ol.children[i].className='circle';
ol.children[ci].className='click_circle';
}
})
//左侧按钮
arrow_l.addEventListener('click',function(){
if(flag){
flag=false;
if(num==0)
{
num=ul.children.length-1;
ul.style.left=-num*focusWith +'px';
}
num--;
animate(ul,-num*focusWith,function(){
flag=true;
});
//点击按钮后小圆圈跟随一起变化
ci--;
//如果circle < 0说明第一张图片,则小圆圈要改为第4个小圆圈(3)
if(ci<0)
ci=ol.children.length-1;
//圆圈样式
for(var i=0;i<ol.children.length;i++)
ol.children[i].className='circle';
ol.children[ci].className='click_circle';
}
})
var timer=setInterval(function(){
arrow_r.click();//手动点击事件
},1000);
})
animate.js:
function animate(obj,target,callback){
//先清除以前的定时器,只保留当前的一个定时器
clearInterval(obj.timer);
obj.timer=setInterval(function(){
if(obj.offsetLeft==target){
clearInterval(obj.timer);
callback && callback();//短路运算
}
var pace=(target-obj.offsetLeft)/10;
pace=pace>0?Math.ceil((target-obj.offsetLeft)/10):Math.floor((target-obj.offsetLeft)/10);
obj.style.left=obj.offsetLeft+pace+"px";
},15)
}