PC端网页特效笔记

PC端网页特效

1.元素偏移量 offset系列

1.1offset概述

偏移量,使用相关属性可以动态的得到元素的位置(偏移)、大小等

获得 元素 距离 带有定位的父元素的 位置

获得 元素 自身的大小(宽高)

注意:返回的数值都不带单位

常用属性和作用:

element.offsetParent
返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body
element.offsetTop
返回元素相对带有定位父元素上方的偏移
element.offsetLeft
返回元素相对带有定位父元素左边框的偏移

.father{
    width: 100px;
    height: 100px;
    background-color: pink;

}
.son{
    width: 60px;
    height: 60px;
    background-color: purple;
    margin-left: 30px;
}
<div class="father">
    <div class="son"></div>
</div>
var father=document.querySelector('.father');
var son=document.querySelector('.son')
//可以得到元素的偏移 位置
console.log(father.offsetTop);
console.log(father.offsetLeft);
//以带有定位的父元素为准, 此时父元素没定位position(或者无父元素),则以body为准
console.log(son.offsetLeft);

element.offsetWidth
返回自身包括padding、边框、 内容区的宽度,返回数值不带单位
element.offsetHeight
返回自身包括padding.边框、内容区的高度,返回数值不带单位

//可以得到宽高 包含padding+border+width
var w=document.querySelector('.w');
console.log(w.offsetWidth);//100
console.log(w.offsetHeight);//100

1.2offset与style区别

offset

  • offset 可以得到任意样式表中的样式值
  • offset 系列获得的数值是没有单位的
  • offsetWidth 包含padding+ border +width
  • offsetWidth 等属性是只读属性.只能获取不能赋值
  • 所以, 我们想要获取元素大小位置,用offset更合适

style

  • style 只能得到行内样式表中的样式值
  • style.width 获得的是带有单位的字符串
  • style.width 获得不包含padding和border的值
  • style.width是可读写属性 ,可以获取也可以赋值
  • 所以, 我们想要给元素更改值,则需要用style改变

1.3使用

案例:获取鼠标在盒子内的坐标

分析:

1.在盒子内点击 想要得到鼠标距离盒子的距离

2.首先得到鼠标在页面中的坐标(e.pageX,e.pageY)

3.其次得到盒子在页面中的距离(box.offsetLeft,box.offsetTop)

4.相减得到

5.如果想要移动一下鼠标,就获取新的坐标,使用鼠标移动事件mousemove

        .w{
            width: 100px;
            height: 100px;
            background-color: #767171;
            margin-left:30px;
            margin-top: 30px;
            /*padding: 10px;*/
        }

    </style>

</head>
<body>

<div class="w"></div>

<script>
    var w=document.querySelector('.w');
    w.addEventListener('click',function (e) {
        var x=e.pageX-this.offsetLeft;
        var y=e.pageY-this.offsetTop;
        this.innerHTML='x:'+x+'y:'+y;
    })

</script>
var w=document.querySelector('.w');
w.addEventListener('mousemove',function (e) {
    var x=e.pageX-this.offsetLeft;
    var y=e.pageY-this.offsetTop;
    this.innerHTML='x:'+x+'y:'+y;
})
案例:拖动模态框(弹出框)

样式未完善

1.点击弹出层,会弹出模态框,并且显示灰色半透明的遮挡层

2.点击关闭按钮,可以关闭,并且同时关闭灰色半透明遮挡层

3.鼠标放到模态框最上边一行,可以按住鼠标拖拽模态框在页面移动

4.鼠标松开,可以停止拖动模态框移动

5.鼠标按下:mousedown 移动:mousemove 松开:mouseup

6.拖拽过程:鼠标移动过程中,获得最新的赋值给模态框的left和top值,这样模态框就跟着鼠标走了

7.鼠标按下触发的事件源是最上边一行,就是title

8.鼠标的坐标减去鼠标在盒子内的坐标,是模态框真正的位置

9.鼠标按下,得到鼠标在盒子的坐标,鼠标移动,模态框坐标:鼠标坐标减去盒子坐标

注意移动事件写到按下事件里边

    <style>

        .login-header{
            text-align: center;
        }
       #link{
            text-decoration: none;
            color: #222222;
        }
        .login{
            display: none;
            width:300px;
            height: 150px;
            line-height: 25px;
            border: 1px solid #e1e1e1;
            background-color: white;
            text-align: center;
            z-index: 999;
            /*margin-top:50px ;*/
            /*margin-left: 250px;*/
            position: fixed;
            left: 50%;
            top:50%;
            transform: translate(-50%,-50%);/*固定定位时垂直水平居中*/
        }
        .login-title{
            /*position: absolute;*/

            text-align: center;
        }
        .close-login{
            color: #222222;
            /*text-align: right;*/
            width: 100%;
            text-decoration: none;
        }
        .login-title span{
            position: absolute;
            right: 15px;
        }
        .login-bg{
            display: none;
            width: 100%;
            height: 100%;
            position: fixed;
            top:0;
            left: 0;
            background: rgba(0,0,0, .3);
        }
    </style>
</head>
<body>
<div class="login-header">
    <a href='javascript:;' id='link'>点击,弹出登录框</a>
</div>
<div class="login">
    <div class="login-title" id="title">
        登录会员
        <span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
    </div>
    <div class="login-content">
        <div class="login-input">
            <label>用户名:</label>
            <input type="text" placeholder="请输入用户名" name="username" id="username" class="username">
        </div>
        <div class="login-input">
            <label>登录密码:</label>
            <input type="password" name="password" id="password" class="password">
        </div>
    </div>
    <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录</a> </div>
</div>
<!--遮盖层-->
<div id="bg" class="login-bg"></div>

<script>
    var login=document.querySelector('.login');
    var bg=document.querySelector('.login-bg');
    var link=document.querySelector('#link');
    var closeBtn=document.querySelector('#closeBtn');
    var title=document.querySelector('#title');

    link.addEventListener('click',function () {
        bg.style.display='block';
        login.style.display='block';
    })

    closeBtn.addEventListener('click',function () {
        bg.style.display='none';
        login.style.display='none';
    })

    title.addEventListener('mousedown',function (e) {
        var x=e.pageX-login.offsetLeft;//鼠标坐标
        var y=e.pageY-login.offsetTop;

        document.addEventListener('mousemove',move)
        function move(e) {
            login.style.left = e.pageX-x+'px';
            login.style.top=e.pageY-y+'px';

        }
        document.addEventListener('mouseup',function () {
            document.removeEventListener('mousemove',move)
        })

    })


</script>
案例:仿京东图片放大镜

分析:

1.分三个功能模块

2.鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开则隐藏

3.黄色遮挡层跟随鼠标

4.大图盒子显示黄色处的大图

5.遮挡层移动,大图片跟随移动

遮挡层移动距离/遮挡层最大移动距离=大图片移动距离/大图片最大移动距离

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>手机详情页!</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .wai{
            width: 300px;
            height: 300px;
            border: 1px solid red;

            position: absolute;
            top:30px;
            left: 30px;
            padding: 0 0 0 0;
            /*font-size: 0;*/
            color: #ff645b;
        }
        #t{
            position: absolute;
            /*vertical-align: middle;*/
            top:0;
            left: 0;
            width: 100%;
            height: 100%;
        }
        .bg{
            display: none;
            position: absolute;
            top:0;
            left: 0;
            width:100px ;
            height: 100px;
            background-color: #ff645b;
            opacity:.5 ;
        }
        .right{
            display: none;
            width: 300px;
            height: 300px;
            position: absolute;
            /*top:30px;*/
            left: 336px;
            background-color: #222222;
            z-index: 999;
            overflow: hidden;
        }
        .dt{
            position: absolute;
            top:0;
            left: 0;
        }
    </style>

</head>

<body>
<div class="wai">
<!--    llasdads-->
    <img src="../resource/01.jpg" id="t">
    <div class="bg"></div>
    <div class="right">
        <img src="../resource/01.jpg" id="dt" class="dt">
    </div>

</div>

</body>
<script>
    var  wai=document.querySelector('.wai');
    var bg=document.querySelector('.bg');
    var right=document.querySelector('.right');

    wai.addEventListener('mouseover',function () {
        bg.style.display='block';
        right.style.display='block';

    })
    wai.addEventListener('mouseout',function () {
        bg.style.display='none';
        right.style.display='none';

    })

    wai.addEventListener('mousemove',function (e) {
        //先计算出鼠标在盒子内的坐标
        var x=e.pageX-this.offsetLeft;//父级无定位
        var y=e.pageY-this.offsetTop;
        // console.log(x,y);
        var bgX=x-bg.offsetWidth/2;
        var bgY=y-bg.offsetHeight/2;
        //如果遮盖层x小于了0,就让他停在0的位置
        /*if (bgX<=0){
            bgX=0;
        } else if(bgX>=wai.offsetWidth-bg.offsetWidth){
            bgX=wai.offsetWidth-bg.offsetWidth;
        }
        if (bgY<=0){
            bgY=0;
        } else if(bgY>=wai.offsetHeight-bg.offsetHeight){
            bgY=wai.offsetHeight-bg.offsetHeight;
        }

        bg.style.left=bgX+'px';
        bg.style.top=bgY+'px';*/
//遮挡层的最大移动距离
        var bgMax=wai.offsetWidth-bg.offsetWidth;

        if (bgX<=0){
            bgX=0;
        } else if(bgX>=bgMax){
            bgX=bgMax;
        }
        if (bgY<=0){
            bgY=0;
        } else if(bgY>=bgMax){
            bgY=bgMax;
        }
        bg.style.left=bgX+'px';
        bg.style.top=bgY+'px';
        //大图
        var dt=document.querySelector('.dt');
        //大图片最大移动距离
        var dtMax=dt.offsetWidth-right.offsetWidth;
        //大图片的移动距离
        var dtX=bgX*dtMax/bgMax;
        var dtY=bgY*dtMax/bgMax;
        dt.style.left=-dtX+'px';
        dt.style.top=-dtY+'px';


    })
</script>

</html>

2.元素可视区 client系列

2.1概述

client即客户端 使用client系列的相关属性来获取元素可视区的相关信息,通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等

client系列属性和作用
element.clientTop:返回元素上边框的大小
element.lientLeft:返回元素左边框的大小
element.cientWidth:返回自身包括padding.内容区的宽度,不含边框,返回数值不带单位
element.lientHeight:返回自身包括padding、 内容区的高度,不含边框,返回数值不带单位

2.2使用

案例:淘宝flexible.js源码分析

立即执行函数(function(){})()

主要作用:创建一个独立的作用域,避免了命名冲突

//立即执行函数:不需要调用,立马能够自己执行
//普通
  function fn() {
      console.log(1);
  }
  fn();
//立即执行函数  写法
//(function () {})() 后边的()表示调用  或者(function () {}() );

(function sum0(a,b) {
    console.log(2);
    console.log(a+b);//3
    var num=10;
})(1,2);//()看做调用函数 两个立即执行函数之间必须加; 不然会报错

    (function sum(a,b) {
        console.log(a+b);//5
        var num=10;
    }(2,3));//这种的必须加;
//3.立即执行函数最大的作用就是 独立创建了一个作用域

3.元素滚动scroll系列属性

3.1概述

滚动的 使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等

scroll系列属性和作用
element.scrollTop:返回被卷去的上例距离,返回数值不带单位
element.scrolleft:返回被卷去的左侧距离,返回数值不带单位
element.scrollWidth:返回自身实际的宽度,不含边框,返回数值不带单位
element.scrolHeight:返回自身实际的高度,不含边框,返回数值不带单位

3.2使用

案例:仿淘宝固定侧边栏

分析:

1.原先侧边栏是绝对定位

2.当页面滚动到一定位置,侧边栏改为固定位置

页面继续滚动,会让返回顶部显示出来

3.因为是页面滚动,所以事件源是ducument

4.滚动到某个位置,就是判断页面被卷上去的上部值

5.页面被卷去的头部:可以通过window.pageYOffset 获得 如果是被卷去的左侧 换成X

6.注意:元素被卷去的头部是element.scrollTop,如果是页面被卷去的头部则是window.pageYOffset

  <style>
        .a1{

            width: 1000px;
            height: 400px;
            background-color: #ff645b;
            margin: 10px auto;
        }
        .a2{
            width: 1000px;
            height: 700px;
            background-color: #333333;
            /*position: relative;*/
            /*top:10px;*/
            margin: 10px auto;
        }
        .a3{
            width: 1000px;
            height: 900px;
            background-color: #84c0ba;
            /*position: relative;*/
            margin: 10px auto;

        }
        .c {
            width: 50px;
            height: 120px;
            background-color: #b4ff0d;
            position: absolute;
            top: 460px;
            left:50%;
            margin-left: 500px;
        }

        span{
             display: none;
            position: absolute;
            bottom: 0;
        }
    </style>

</head>

<body>
<div class="a1" id="a1">
    111
</div>
<div class="a2">222</div>
<div class="a3">333</div>
<div class="c"><span class="gb"><a href="#a1">返回顶部</a></span></div>
</body>

<script>
    var c=document.querySelector('.c');
    var a2=document.querySelector('.a2');
    // console.log(a2.offsetTop);
    //侧边栏固定定位后 距离顶部距离应该不变了
    var ctop=c.offsetTop-a2.offsetTop;

    var a3=document.querySelector('.a3');
    var gb=document.querySelector('.gb');
     var a3top=a3.offsetTop;

    document.addEventListener('scroll',function () {
        // console.log(window.pageYOffset);//页面被卷去的头部
        if (window.pageYOffset>=a2.offsetTop){
            c.style.position='fixed';
            c.style.top=ctop+'px';
        }else {
            c.style.position='absolute';
            c.style.top=460+'px';
        }
        //页面滚动到a3时候 显示返回顶部
        if (window.pageYOffset>=a3top){
            gb.style.display='block';
        }else {
            gb.style.display='none';
        }
    })

4.三大系列总结

三大系列大小对比 作用
element.offsetWidth
返回自身包括padding、边框、 内容区的宽度,返回数值不带单位
element.clientWidth
返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
element,scrollWidth
返回自身实际的宽度,不含边框,返回数值不带单位

主要用法:

  1. offset系列 经常用于获得元素位置offsetleft offsetTop

  2. client 经常用于获取元素大小clientWidth clientHeight

  3. scroll经常用于获取滚动距离 scrollTop scrolleft

    4.注意页面滚动的距离通过 window . pagexoffset获得

5.mouseenter和mouseover的区别***

var fa=document.querySelector('.fa');
var son=document.querySelector('.son');
fa.addEventListener('mouseover',function () {
    console.log(11);
})
fa.addEventListener('mouseenter',function () {
    console.log(22);
})

都是当鼠标移动到元素上时就会触发

但是mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发,

mouseenter 只有鼠标经过自身盒子才会触发

原因是:mouseenter不会冒泡

跟mouseenter搭配 鼠标离开 mouseleave 同样不会冒泡

6.动画函数封装

6.1动画实现原理

核心原理:通过定时器setInterval()不断移动盒子位置

步骤:

1.获得盒子当前位置

2.让盒子在当前位置加上1个移动距离

3.利用定时器不断重复这个操作

4.结束定时器的条件

5.注意此元素需要 添加定位,才能使用element.style.left

 div{
            position: absolute;
            width: 200px;
            height: 200px;
            background-color: pink;
            left:0 ;
        }

var div=document.querySelector('div');
var timer=setInterval(function () {
    if (div.offsetLeft>=400){
        clearInterval(timer);//盒子停止移动也就是停止定时器
    }
    div.style.left=div.offsetLeft+5+'px';
},30)

6.2动画函数简单封装

注意函数需要传递2个参数,动画对象和移动到的距离

 div{
            position: absolute;
            width: 200px;
            height: 200px;
            background-color: pink;
            left:0 ;
        }
        span{
            position: absolute;
            left: 0;
            top: 220px;
            display: block;
            width: 50px;
            height: 50px;
            background-color: #84c0ba;
        }

//简单动画函数封装 obj目标对象 target目标位置
function animate(obj,target) {
    var timer=setInterval(function () {
        if (obj.offsetLeft>=target){
            clearInterval(timer);//盒子停止移动也就是停止定时器
        }
        obj.style.left=obj.offsetLeft+5+'px';
    },30)
}
var div=document.querySelector('div');
var span=document.querySelector('span');
animate(span,300);//调用
animate(div,400);

6.3动画函数给不同元素记录不同定时器

如果多个元素都使用这个动画函数,每次都要var声明定时器,我们可以给不同元素使用不同的定时器(自己专门用自己的定时器)

核心原理:利用js是一门动态语言,可以很方便的给当前对象添加属性

上边的代码 调用一次函数就需要开辟一次内存空间

上边代码优化:

//给不同元素指定不同定时器
//简单动画函数封装 obj目标对象 target目标位置
function animate(obj,target) {
    obj.timer=setInterval(function () {
        if (obj.offsetLeft>=target){
            clearInterval(obj.timer);//盒子停止移动也就是停止定时器
        }
        obj.style.left=obj.offsetLeft+5+'px';
    },30)
}
var div=document.querySelector('div');
var span=document.querySelector('span');
animate(span,300);
animate(div,400);

6.4缓动动画

缓动效果 原理:让元素运动速度有所变化,最常见的是让速度慢慢停下来

思路:

1.让盒子每次移动的距离慢慢变小,速度就会慢慢降下来

2.核心算法:(目标值-现在的位置)/10 作为每次移动的距离步长

3.停止的条件:让当前盒子位置等于目标位置就停止定时器

//给不同元素指定不同定时器
//简单动画函数封装 obj目标对象 target目标位置
function animate(obj,target) {
    //速度加快解决方法
    clearInterval(obj.timer);
    obj.timer=setInterval(function () {
        //步长值写到定时器的里面
        //var step=(target-obj.offsetLeft)/10
        //把步长值改为整数,防止出现小数问题
            var step=Math.ceil(target-obj.offsetLeft)/10;//往大了取
        if (obj.offsetLeft==target){
            clearInterval(obj.timer);//盒子停止移动也就是停止定时器
        }
        //
        obj.style.left=obj.offsetLeft+step+'px';
    },40)
}
var div=document.querySelector('div');
var span=document.querySelector('span');

var btn=document.querySelector('button');
btn.addEventListener('click',function () {
    //当不断点击按钮,这个元素速度会越来越快,因为开启了太多定时器
    //解决方法是 让元素只有一个定时器执行 每次都清楚定时器 如上
    animate(span,800);
    animate(div,500)
})
//匀速动画 就是盒子是当前的位置+固定的值
//缓动动画就是 盒子当前的位置+变化的值

回退情况

再点击时 要判断正负

//给不同元素指定不同定时器
//简单动画函数封装 obj目标对象 target目标位置
function animate(obj,target) {
    //速度加快解决方法
    clearInterval(obj.timer);
    obj.timer=setInterval(function () {
        //步长值写到定时器的里面
        //把步长值改为整数,防止出现小数问题
        // 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);//盒子停止移动也就是停止定时器
        }
        //
        obj.style.left=obj.offsetLeft+step+'px';
    },40)
}
var div=document.querySelector('div');
var span=document.querySelector('span');

var btn1=document.querySelector('#btn1');
btn1.addEventListener('click',function () {
    //当不断点击按钮,这个元素速度会越来越快,因为开启了太多定时器
    //解决方法是 让元素只有一个定时器执行 每次都清楚定时器 如上
    animate(span,800);
    animate(div,500);
})
//匀速动画 就是盒子是当前的位置+固定的值
//缓动动画就是 盒子当前的位置+变化的值
var btn2=document.querySelector('#btn2');
btn2.addEventListener('click',function () {
    animate(div,800);
})

6.5动画函数添加回调函数

回调函数原理:函数可以作为一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,在执行穿进去的这个函数,这个函数就叫回调

回调函数写的位置:定时器结束的位置

//给不同元素指定不同定时器
//简单动画函数封装 obj目标对象 target目标位置
function animate(obj,target,callback) {
    // console.log(callback);
    // callback();调用

    //速度加快解决方法
    clearInterval(obj.timer);
    obj.timer=setInterval(function () {
        //步长值写到定时器的里面
        //把步长值改为整数,防止出现小数问题
        // 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();
            }
        }
        //
        obj.style.left=obj.offsetLeft+step+'px';
    },40)
}
var div=document.querySelector('div');
var span=document.querySelector('span');

var btn1=document.querySelector('#btn1');
btn1.addEventListener('click',function () {
    //当不断点击按钮,这个元素速度会越来越快,因为开启了太多定时器
    //解决方法是 让元素只有一个定时器执行 每次都清楚定时器 如上
    animate(span,800);
    animate(div,500);
})
//匀速动画 就是盒子是当前的位置+固定的值
//缓动动画就是 盒子当前的位置+变化的值
var btn2=document.querySelector('#btn2');
btn2.addEventListener('click',function () {
    animate(div,800,function () {
        // alert('hello');
        div.style.backgroundColor='red';

    });

})
案例:使用
    <style>

        .con{
            position: absolute;
            width: 150px;
            height: 50px;
            background-color: pink;
            left: 0px;
            top:0px;
            z-index: -1;
        }
        .slider{
            position: absolute;
            right: 0px;
            width: 50px;
            height: 50px;
            background-color: #84c0ba;

        }
    </style>

</head>

<body>
<div class="slider">
    <span></span>
    <div class="con">问题反馈</div>
</div>


</body>

<script>
    var slider=document.querySelector('.slider');
    var con=document.querySelector('.con');
    slider.addEventListener('mouseenter',function () {
        animate(con,-100,function () {
            //等动画执行完毕后 改为右箭头
            slider.children[0].innerHTML='→';
        });

    })
    slider.addEventListener('mouseleave',function () {
        animate(con,0,function () {
            slider.children[0].innerHTML='←';
        });

    })


    //给不同元素指定不同定时器
    //简单动画函数封装 obj目标对象 target目标位置
    function animate(obj,target,callback) {
        // console.log(callback);
        // callback();调用

        //速度加快解决方法
        clearInterval(obj.timer);
        obj.timer=setInterval(function () {
            //步长值写到定时器的里面
            //把步长值改为整数,防止出现小数问题
            // 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();
                }
            }
            //
            obj.style.left=obj.offsetLeft+step+'px';
        },40)
    }

</script>

7.常见网页特效案例

7.1网页轮播图

也称为焦点图

功能需求:

1.鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮

2.点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理

3.图片播放的同时,下面小圆圈模块跟随一起变化

4.点击小圆圈,可以播放相应图片(ul移动 索引号*图片宽度)

5.鼠标不经过轮播图,轮播图模块,自动停止播放

节流阀:

防止轮播图按钮连续点击造成播放过快。
节流阀目的:当上-一个函数动画内容执行完毕,再去执行下一个函数动画 ,让事件无法连续触发。
核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

开始设置一个变量var flag = true;
if(fla g) (flag= false; do something)关闭水龙头
利用回调函数动画执行完毕,flag=true 打开水龙头

<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        li{
            list-style: none;
        }

        .k{
            position: relative;
            width: 500px;
            height: 400px;
            margin: 100px auto;
            padding: 0;
            background-color: #84c0ba;
            /*text-align: center;*/
            overflow: hidden;
        }

        .arrow-l{
            display: none;
            text-align: center;
            text-decoration: none;
            position: absolute;
            left: 0px;
            top: 200px;
            width: 30px;
            height: 30px;
            background-color: #767171;
            opacity: .5;
            z-index: 999;
        }
        .arrow-r{
            display: none;
            text-align: center;
            text-decoration: none;
            position: absolute;
            right: 0px;
            top: 200px;
            width: 30px;
            height: 30px;
            background-color: #767171;
            opacity: .5;
            z-index: 999;
        }
        .k ul{
            position: absolute;
            top:0;
            left: 0;
            width: 600%;
            height: 100%;
            padding: 0;
            margin: 0;
        }

        .k ul li{
            float: left;
            height: 100%;
            /*width: 100%;*/
        }
        .k ul li img{
            height: 100%;
            width: 500px;
        }

        .circle{
            position: absolute;
            bottom: 10px;
            left: 200px;
        }
        .circle li{
            float: left;
            width: 8px;
            height: 8px;
            border: 1px solid #767171;
            margin: 0 3px;
            /*圆角*/
            border-radius: 50%;
        /*    鼠标经过显示小手*/
            cursor: pointer;
        }
        .current{
            background-color: #fff;
        }


    </style>

</head>

<body>
<div class="k">
<!--    左侧按钮-->
    <a href="javaccript:;" class="arrow-l">&lt;</a>
<!--    右侧按钮-->
    <a href="javaccript:;" class="arrow-r">&gt;</a>

    <ul>
        <li>
            <a href="#"><img src="../resource/01.jpg"></a>
        </li>
        <li>
            <a href="#"><img src="../resource/001.png"></a>
        </li>
        <li>
            <a href="#"><img src="../resource/01.jpg"></a>
        </li>
        <li>
            <a href="#"><img src="../resource/001.png"></a>
        </li>
    </ul>
<!--    //小圆圈-->
    <ol class="circle">
        <!--<li></li>
        <li class="current"></li>
        <li></li>
-->
    </ol>

</div>


</body>

<script>
    //函数在前边 因为后边的依赖于动画函数

    //给不同元素指定不同定时器
    //简单动画函数封装 obj目标对象 target目标位置
    function animate(obj,target,callback) {
        // console.log(callback);
        // callback();调用

        //速度加快解决方法
        clearInterval(obj.timer);
        obj.timer=setInterval(function () {
            //步长值写到定时器的里面
            //把步长值改为整数,防止出现小数问题
            // 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();
                }*/
                callback &&callback();//短路运算
            }
            //
            obj.style.left=obj.offsetLeft+step+'px';
        },40)
    }



    var k=document.querySelector('.k');
    var kwidth=k.offsetWidth;
    var arrowl=document.querySelector('.arrow-l');
    var arrowr=document.querySelector('.arrow-r');
    //1;鼠标经过k就显示按钮
     k.addEventListener('mouseenter',function () {
        arrowl.style.display='block';
         arrowr.style.display='block';
         //停止定时器
         clearInterval(timer);
         timer=null;//清楚定时器变量
     })
    k.addEventListener('mouseleave',function () {
        arrowl.style.display='none';
        arrowr.style.display='none';
        timer=setInterval(function () {
            //手动调用点击事件
            arrowr.click();
        },2000)

    })


    //2.根据图片数动态生成圆圈个数
    var ul=k.querySelector('ul');
    var ol=k.querySelector('.circle');
     for (var i=0;i<ul.children.length;i++){
         //创建小li
         var li=document.createElement('li');
         //记录当前小圆圈的索引号 通过自定义属性来做
         li.setAttribute('index',i);
         //插入到ol
         ol.appendChild(li);
         //3.小圆圈排他思想 在生成同时 绑定点击事件
         li.addEventListener('click',function () {
            //干掉所有人
             for (var i=0;i<ol.children.length;i++){
                 ol.children[i].className='';
             }
             //留下我自己
             this.className='current';
             //4.图片移动 移动的是ul
             //ul的移动距离 索引号*图片宽度 注意是负值
             //当点击某个li 拿到索引号
             var index=this.getAttribute('index');
             //当我们点击了某个小li 就把这个li的索引号给num 给circle
             num=index;
            circle=index;
             animate(ul,-index*kwidth);
         })
     }

     //5.把ol里面的第一个li设为白色
    ol.children[0].className='current';

     //6.克隆第一张图片li 放到ul最后面
    var first=ul.children[0].cloneNode(true);
    ul.appendChild(first);
    //7.点击右侧按钮 图片滚动一张
    //图片无缝滚动:把ul的第一个复制一份 放到ul的最后面,当滚动到克隆的图片时,让ul快速跳到最左侧:left为0
    //同时num=0 从头开始
    var num=0;
    //circle控制小圆圈播放
    var circle=0;
    //节流阀
    var flag=true;

    arrowr.addEventListener('click',function () {
        if (flag) {
            flag = false;

            //如果走到最后一张 快速复原
            if (num == ul.children.length - 1) {
                ul.style.left = 0;
                num = 0;
            }
            num++;

            animate(ul, -num * kwidth,function () {
                flag=true;
            });
            //8.点击右侧按钮 小圆圈跟随变化
            circle++;
            if (circle == ul.children.length - 1) {
                circle = 0;
            }
            circleChange();
        }

    });

    arrowl.addEventListener('click',function () {
        if (flag) {
            flag = false;

            //如果走到最后一张 快速复原
            if (num == 0) {
                num = ul.children.length - 1;
                ul.style.left = -num * kwidth + 'px';
            }
            num--;

            animate(ul, -num * kwidth,function () {
                flag=true;
            });
            //8.点击右侧按钮 小圆圈跟随变化
            circle--;
            /* if (circle<0){
            circle=ol.children.length-1;
        }*/
            circle = circle < 0 ? ol.children.length - 1 : circle;
            circleChange();
        }

    });
    function circleChange() {
        //先清除其余小圆圈的类名
        for (var i=0;i<ol.children.length;i++){
            ol.children[i].className='';
        }
        //再添加
        ol.children[circle].className='current';

    }
    //自动播放
    var timer=setInterval(function () {
        //手动调用点击事件
        arrowr.click();
    },2000)



</script>

</html>

7.2带有动画的返回底部

<script>
    function animate(obj,target,callback) {
        // console.log(callback);
        // callback();调用

        //速度加快解决方法
        clearInterval(obj.timer);
        obj.timer=setInterval(function () {
            //步长值写到定时器的里面
            //把步长值改为整数,防止出现小数问题
            // 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();
                }*/
                //简单写法
                callback &&callback();//短路运算
            }
            //
            // obj.style.left=window.pageYOffset+step+'px';
            window.scroll(0,window.pageYOffset+step );
        },40)
    }

    var c=document.querySelector('.c');
    var a2=document.querySelector('.a2');
    // console.log(a2.offsetTop);
    //侧边栏固定定位后 距离顶部距离应该不变了
    var ctop=c.offsetTop-a2.offsetTop;

    var a3=document.querySelector('.a3');
    var gb=document.querySelector('.gb');
    var a3top=a3.offsetTop;

    document.addEventListener('scroll',function () {
        // console.log(window.pageYOffset);//页面被卷去的头部
        if (window.pageYOffset>=a2.offsetTop){
            c.style.position='fixed';
            c.style.top=ctop+'px';
        }else {
            c.style.position='absolute';
            c.style.top=460+'px';
        }
        //页面滚动到a3时候 显示返回顶部
        if (window.pageYOffset>=a3top){
            gb.style.display='block';
        }else {
            gb.style.display='none';
        }
    })

    gb.addEventListener('click',function () {
        //x,y直接写数字

        // window.scroll(0,0);//回到顶部
        animate(window,0);
    })

</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值