css和html代码

<!doctype html>
<html lang="en">
 <head>
      <meta charset="UTF-8">
      <meta name="Keywords" content="">
      <meta name="Description" content="">
      <title>document</title>
      <style type="text/css">
            *{
                padding:0;
                margin:0
            }
            img{
                vertical-align:middle;
            }
            #box{
                width:1250px;
                height:360px;
                margin:100px auto;
                font-family:'Microsoft yahei';
            }
            #box ul li{
                list-style:none;
                float:left;
                margin:0 10px;
                position:relative;
                overflow:hidden;
            }
            #box ul li a{
                width:230px;
                height:360px;
                position:absolute;
                left: 0;
                top: 360px;
                background:url("images/new-bg.png");
                text-decoration:none;
            }
            #box ul li a p{
                color:#fff;
                font-size:14px;
                text-align:center;
            }
            #box ul li a p.p1{
                padding-top:160px;
            }
        </style>
 </head>
        <body>
            <div id='box'>
                <ul id="list">
                    <li>
                        <img src='images/1.jpg'/>
                        <a href='#'>
                            <p class='p1'>秋冬上新 领券立减20</p>
                            <p>点击进入</p>
                        </a>
                    </li>
                    <li>
                        <img src='images/2.jpg'/>
                        <a href='#'>
                            <p class='p1'>钜惠满138减15</p>
                            <p>点击进入</p>
                        </a>
                    </li>
                    <li>
                        <img src='images/3.jpg'/>
                        <a href='#'>
                            <p class='p1'>冬装尖品 强势登陆</p>
                            <p>点击进入</p>
                        </a>
                    </li>
                    <li>
                        <img src='images/4.jpg'/>
                        <a href='#'>
                            <p class='p1'>十一国庆除出游季</p>
                            <p>购新衣才够【型】</p>
                        </a>
                    </li>
                    <li>
                        <img src='images/5.jpg'/>
                        <a href='#'>
                            <p class='p1'>秋上新</p>
                            <p>点击进入</p>
                        </a>
                    </li>
                </ul>
            </div>
</html>

js实现思路

  • 什么是js语言?js语言是基于原型的动态解释性语言,其基本操作分为css样式操作和dom节点操作。基于原型:存在对象、声明,就有原型。动态解释性:语言可以在任何环境下运行,没有限制。js不仅仅能够用于特效,插件框架开发、机器学习、数据分析、人工智能,都可以通过js实现
  • 实现简单的鼠标划入操作思路:

(1)获取dom元素

(2)考虑两个事件:mouseenter、mouseleave,注册事件实现移入移出操作。

元素获取

  • 获取元素有三种方法:原生js方法(get方法)、$方法、query方法。其中get方法由js原生提供,获取速度最优,$和query方法都是由get系列封装而成。不同在于$是jQuery提供,性能最差;query由html5提供,而且经过了优化,获取速度仅次于get原生方法。
  • 在这里我们使用原生js方法实现:
<script>
                var oBox=document.getElementById('box');
                var aLi=oBox.getElementsByTagName('li');
 </script>

使用for循环进行事件注册

  • for循环可以给每个li绑定一个事件,从而实现了事件注册
//使用for循环进行事件注册
                for(var i=0,aLiLen=aLi.length;i<aLiLen;i++){
                    //这样较for(var i=0;i<aLi.length;i++)性能更优,因为不必每次计算aLi.length
                    aLi[i].onmouseenter=function(){
                        console.log(1);
                    }
                }
  • 首先注意的是,由于box有多个li子元素,所以aLi是一个伪数组。即具有数组的属性(下标、长度),而没有数组的方法(foreach、push、sort)。其次注意,enter、leave、over、out的区别:enter、leave在不冒泡条件下进行,由外到里;out、over在冒泡条件下进行,由里到外。冒泡:事件的执行顺序由子集向父集发出,即由里到外。
  • 但是,一般情况下,我们不采用for循环进行事件注册。原因:

(1)当事件绑定特别多时,容易造成事件覆盖。即只执行后边的事件,前边事件不执行

(2)性能特别差,进行循环遍历为每个li绑定事件;但是鼠标不进入的话,就不会触发事件。这样会造成浏览器加载资源的浪费(当一万个事件时...)

因此,我们通常采用事件代理(事件委托)实现事件注册。事件代理基于事件监听实现,不必给每个li进行绑定

基于事件监听的事件代理

  • 在实现特效时,首先要学会观察,不要着急一上来就干。思考此特效的实现过程:鼠标移入-》获取鼠标坐标-》获取元素宽高,进而得到元素距离浏览器各边的大小-》计算鼠标坐标和四条边的距离-》哪边的绝对值最小,就说明从哪边移入(移入瞬间,差值接近0)
  • 若有两个的绝对值是相等的,我们执行哪个事件呢?当然是后边的,因为事件覆盖嘛。
  • 在计算得到四个绝对值中的最小值后,我们加以val的判断,就能得到鼠标是从哪个方向移入或者移出了。但是后边的动画怎么实现呢?我们分两步完成,假设鼠标从上边移入,我们先瞬间令背景图移动到最上边,然后缓慢的移下来。这个动画的实现过程我们使用链式操作实现。链式操作的原理很简单,就是每次方法执行完后返回this对象,这样后面的方法就可以继续在this环境下执行。
       //获取元素
                var oBox=document.getElementById('box');
                var aLi=oBox.getElementsByTagName('li');

                // //使用for循环进行事件注册
                // for(var i=0,aLiLen=aLi.length;i<aLiLen;i++){
                //     //这样较for(var i=0;i<aLi.length;i++)性能更优,因为不必每次计算aLi.length
                //     aLi[i].onmouseenter=function(){
                //         console.log(1);
                //     }
                // }

                //基于事件监听的事件代理
                oBox.addEventListener('mouseenter',function(e){
                    //检验和调试
                    //最后的false\true参数表示是否冒泡。默认为false,表示冒泡阶段
                    //console.log(1);//参数为true一次打印多个1;false一次打印一个1
                    //console.log(e);//true一次会触发多个事件,是我们想要的
                    //console.log(e.target.tagName);//确认真的没错

                    //代码优化
                    var target=e.target;

                    if(target.tagName.toLowerCase()=='li'){
                        //得到鼠标移入li瞬间的鼠标坐标
                        var x=e.clientX;
                        var y=e.clientY;

                        //得到li四条边距离浏览器左部和顶部的距离
                        var oT=target.offsetTop;
                        var oB=oT+target.offsetHeight;
                        var oL=target.offsetLeft;
                        var oR=oL+target.offsetWidth;

                        //计算鼠标坐标和四条边的距离,取绝对值
                        var diffT=Math.abs(y-oT);
                        var diffB=Math.abs(y-oB);
                        var diffL=Math.abs(x-oL);
                        var diffR=Math.abs(x-oR);

                        //取最小值为方向
                        var direction=Math.min(diffT,diffB,diffL,diffR);

                        //判断是鼠标移入还是移出
                        var val=e.type.toLowerCase();

                        //console.log(diffT,diffB,diffL,diffR);//检验一下

                        //switch语句选择方向
                        switch(direction){
                            //方法是一样的,只是方向不一样。我们只要封装函数即可
                            case diffT:
                                moveTo('top',val,target);
                                //console.log('从上移入');
                                break;
                            case diffB:
                                moveTo('bottom',val,target);
                                //console.log('从下移入');
                                break;
                            case diffL:
                                moveTo('left',val,target);
                                //console.log('从左移入');
                                break;
                            case diffR:
                                moveTo('right',val,target);
                                //console.log('从右移入');
                                break;
                        }
                    }
                },true);

                function moveTo(aspect,mouse,aim){
                    //aspect表示鼠标移入方向;
                    // mouse表示鼠标
                    // aim表示操作的对象
                    // from瞬间移动的距离
                    // to后来的距离,默认为0
                        if(mouse=='mouseenter'){
                            aim.children[1].css(aspect).enter(aspect);
                        }else{

                        }
                }

                Node.prototype.css=function(aspect){
                    if(aspect=='top'){
                        this.style[aspect]=-360+'px';
                        this.style.left=0;
                    }

                    return this;
                }

                Node.prototype.enter=function(aspect){
                    setTimeout(function(){
                        this.style[aspect]=0+'px';
                        this.style.transition='.3s';
                    }.bind(this),0)
                    //this在此处默认指向windows(因为settimeout是windows调用的函数),我们使用bind强制事件绑定,使其指向当前对象

                    // this.style[aspect]=to+'px';
                    // this.style.transition='.3s';
                    //若不使用setTimeOut伪异步操作的话,会发生事件覆盖,即前边的css被后边的enter覆盖

                    return this;
                }

问题

浏览器打开后,特效有时从上边出来,有时从下边出来,不知道为啥


无欲则刚
76 声望15 粉丝