JavaScript学习(二)动画

来源:互联网 发布:addiction动作数据mmd 编辑:程序博客网 时间:2024/06/05 16:09

Offset

offsetWidth和offsetHight

检测盒子自身宽高+padding+border。
这两个属性,他们绑定在了所有的节点元素上。获取之后,只要调用这两个属性,我们就能够获取元素节点的宽和高。
offset宽/高 = 盒子自身的宽/高 + padding +border;
offsetWidth = width+padding+border;
offsetHeight = Height+padding+border;

offsetLeft和offsetTop

检测距离父盒子有定位的左/上面的距离。
返回距离上级盒子(带有定位)左边s的位置,如果父级都没有定位则以body为准,offsetLeft 从父亲的padding 开始算,父亲的border 不算。在父盒子有定位的情况下,offsetLeft == style.left(去掉px)。

offsetParent

检测父系盒子中带有定位的父盒子节点。
1、返回改对象的父级 (带有定位)
如果当前元素的父级元素没有进行CSS定位(position为absolute或 relative,fixed),offsetParent为body。
2、如果当前元素的父级元素中有CSS定位(position为absolute或relative,fixed),offsetParent取最近的那个父级元素。

offsetLeft和style.left区别

一、最大区别在于offsetLeft可以返回没有定位盒子的距离左侧的位置。
而 style.left不可以
二、offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。
三、offsetTop 只读,而 style.top 可读写。(只读是获取值,可写是赋值)
四、如果没有给 HTML 元素指定过 top 样式,则style.top 返回的是空字符串。

缓动动画

原理

leader=leader+(target-leader)/10;盒子位置 = 盒子本身位置+(目标位置-盒子本身位置)/ 10;动画原理 = 盒子位置 + 步长(步长越来越小)。

offsetLeft和style.left的值的获取问题

offsetLeft获取盒子距离左侧具有定位的父盒子的距离(没有的body),四舍五入取整。
Style.left获取的是具体值。

案例

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        div {            width: 100px;            height: 100px;            background-color: pink;            position: absolute;            left: 0;        }    </style></head><body><button>运动到200</button><button>运动到400</button><div></div><script>    var btn = document.getElementsByTagName("button");    var div = document.getElementsByTagName("div")[0];    //运动到200    btn[0].onclick = function () {        animate(div,200);    }    //运动到400    btn[1].onclick = function () {        animate(div,400);    }    //封装缓动动画    function animate(ele,target) {        //先清定时器        clearInterval(ele.timer);        //定义定时器        ele.timer = setInterval(function () {           //获取步长,步长应该是越来越小            var step = (target - ele.offsetLeft)/10;            //大于0向上取整,小于0向下取整            step = step>0 ? Math.ceil(step) : Math.floor(step);            //动画原理: 目标位置 = 当前位置 + 步长            ele.style.left = ele.offsetLeft + step + "px";            //检测缓动动画有没有停止            if(Math.abs(target - ele.offsetLeft) <= Math.abs(step)){                //处理小数赋值                ele.style.left = target + "px";                clearInterval(ele.timer);            }        },30);    }</script></body></html>

Scroll

scrollWidth和scrollHeight

检测盒子的宽高,不包括border。调用者:节点元素、属性。盒子内容的宽高。(如果有内容超出了,显示内容的高度)。
兼容性:IE567可以比盒子小。IE8+火狐谷歌不能比盒子小。

scrollWidth和scrollHeight不包括border和marginscrollWidth = width + padding;

scrollTop和scrollLeft

网页,被浏览器遮挡的头部和左边部分。
兼容性:
一、未声明 DTD(谷歌只认识他)
document.body.scrollTop
二、已经声明DTD(IE678只认识他)
document.documentElement.scrollTop
三、火狐/谷歌/ie9+以上支持的
window.pageYOffset

只要页面滚动无论向左向右,向上向下,哪怕只有1px,都会触动onscroll事件。

   window.onscroll = function () {        //兼容写法        document.title = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0;   }

获取title、body、head、html标签

document.title — 文档标题;
document.head — 文档的头标签
document.body — 文档的body标签;
document.documentElement — 文档的html标签;html标签并不是通过document.html去访问的;

json的遍历

//jsonvar json = {"aaa":11,"bbb":22};//遍历for(var k in json){    console.log(k); //属性    console.log(json[k]); //值}//compatMode属性,CSS1Compatalert(document.compatMode);//获取key为aaa的值alert(json.aaa);

Scroll()的封装

判断页面有没有DTD约束:

document.compatMode === "BackCompat"BackCompat  未声明CSS1Compat  已经声明
// 封装scrollfunction scroll() {      if(window.pageYOffset != null) {  // ie9+ 高版本浏览器        // 因为 window.pageYOffset 默认的是  0  所以这里需要判断        return {            left: window.pageXOffset,            top: window.pageYOffset        }    }    else if(document.compatMode === "CSS1Compat") {    // 标准浏览器   来判断有没有声明DTD        return {            left: document.documentElement.scrollLeft,            top: document.documentElement.scrollTop        }    }    return {   // 未声明 DTD        left: document.body.scrollLeft,        top: document.body.scrollTop    }}
function scroll(){    //简单封装    return {        "top": window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop,        "left":  window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft    }}

ScrollTo

window.scrollTo ,屏幕跳转,方法可把内容滚动到指定的坐标。
语法:
scrollTo(xpos,ypos)
xpos 必需,要在窗口文档显示区左上角显示的文档的 x 坐标。
ypos 必需,要在窗口文档显示区左上角显示的文档的 y 坐标。

案例

案例一
需求:1、当我们滚动界面的时候,被卷曲的头部超过第二个盒子距离顶部的位置,那么直接给第二个盒子加类名.fixed;2、当我们滚动界面的时候,被卷曲的头部小于第二个盒子距离顶部的位置,那么直接给第二个盒子取消类名.fixed

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        * {            margin: 0;            padding: 0        }        img {            vertical-align: top;        }        .main {            margin: 0 auto;            width: 1000px;            margin-top: 10px;        }        #Q-nav1 {            overflow: hidden;        }        .fixed {            position: fixed;            top: 0;            left: 0;        }    </style>    <!--引入工具js-->    <script src="my.js"></script>    <script>        window.onload = function () {            //1.获取对象            var topDiv = document.getElementById("top");            var height = topDiv.offsetHeight;            var middle = document.getElementById("Q-nav1");            var main = document.getElementById("main");            //2.卷起            window.onscroll = function () {                //判断被卷起的头部的大小                if(scroll().top > height){                    //3.满足条件添加类,否则删除类                    middle.className += " fixed";                    //第二个盒子不占位置,给第三个盒子一个上padding占位置,不出现盒子抖动问题                    main.style.paddingTop = middle.offsetHeight + "px";                }else {                    middle.className = "";                    //清零                    main.style.paddingTop = 0;                }            }        }    </script></head><body>    <div class="top" id="top">        <img src="images/top.png" alt=""/>    </div>    <div id="Q-nav1">        <img src="images/nav.png" alt=""/>    </div>    <div class="main" id="main">        <img src="images/main.png" alt=""/>    </div></body></html>

案例二
需求:屏幕滚动多少,两侧的图片联动向下移动等距离。

window.onload = function () {    var imgArr = document.getElementsByTagName("img");    window.onscroll = function () {        //获取被卷去的头部的值        var val = scroll().top;        //移动两个盒子(缓动移动)        animate(imgArr[0],val+80); //80是图片的高度        animate(imgArr[1],val+80);    }}

案例三
需求:浏览器被卷去的头部超过1000显示小火箭,然后点击小火箭屏幕缓慢移动到最顶端。

window.onload = function () {    //1.获取图片    var img = document.getElementsByTagName("img")[0];    window.onscroll = function () {        //被卷去的距离大于1000显示小火箭,否则隐藏        2.显示隐藏小火箭        if(scroll().top>1000){            img.style.display = "block";        }else{            img.style.display = "none";        }        //每次移动滚动条的时候都给leader赋值,模拟leader获取距离顶部的距离        leader = scroll().top;    }    //3.缓动跳转到页面最顶端(利用我们的缓动动画)    var timer = null;    var target = 0; //目标位置    var leader = 0; //显示区域自身的位置    img.onclick = function () {        //要用定时器,先清定时器        clearInterval(timer);        timer = setInterval(function () {            //获取步长            var step = (target-leader)/10;            //处理步长            step = step>0?Math.ceil(step):Math.floor(step);            leader = leader +step;            //显示区域移动            // window.scrollTo(x,y);浏览器显示区域跳转到指定的坐标            window.scrollTo(0,leader);            //清除定时器            if(leader === 0){                clearInterval(timer);            }        },25);    }}

案例4
需求:点击ol中的li,屏幕滑动到对应的ul中的li的范围。
技术点:
盒子属性:auto:适应盒子自身的宽度或者高度。
盒子属性:100%:适应盒子父盒子的宽度或者高度。
100%子盒子会继承父盒子的宽高。父盒子继承body宽高。Body继承html的宽高。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        * {            margin: 0;            padding: 0;        }        body,html {            height: 100%;        }        ul {            list-style: none;            height: 100%;        }        ul li {            height: 100%;        }        ol {            list-style: none;            position: fixed;            top: 80px;            left: 50px;        }        ol li {            width: 50px;            height: 50px;            border: 1px solid #000;            text-align: center;            line-height: 50px;            margin-top: -1px;            cursor: pointer;        }    </style></head><body>    <ul>        <li>鞋子区域</li>        <li>袜子区域</li>        <li>裤子区域</li>        <li>裙子区域</li>        <li>帽子区域</li>    </ul>    <ol>        <li>鞋子</li>        <li>袜子</li>        <li>裤子</li>        <li>裙子</li>        <li>帽子</li>    </ol>    <script src="animate.js"></script>    <script>        //0.获取元素        var ul = document.getElementsByTagName("ul")[0];        var ol = document.getElementsByTagName("ol")[0];        var ulLiArr = ul.children;        var olLiArr = ol.children;        var target = 0;var leader = 0;var timer = null;        //1.指定ul和ol中的li的背景色,对应的li背景色相同        //设置一个数组,里面装颜色,然指定的颜色给数组中的指定元素        var arrColor = ["pink","blue","yellow","orange","green"];        //利用for循环给两个数组的元素上色        for(var i=0;i<arrColor.length;i++){            //上色            ulLiArr[i].style.backgroundColor = arrColor[i];            olLiArr[i].style.backgroundColor = arrColor[i];            //属性绑定索引值            olLiArr[i].index = i;            //2.老三步。(并绑定事件)循环绑定,为每一个li绑定点击事件            olLiArr[i].onclick = function () {                //***获取目标位置                    //获取索引值。                target = ulLiArr[this.index].offsetTop;                //要用定时器,先清除定时器                clearInterval(timer);                //3.利用缓动动画原理实现屏幕滑动                timer = setInterval(function () {                    //(1).获取步长                    var step = (target-leader)/10;                    //(2).二次处理步长                    step = step>0?Math.ceil(step):Math.floor(step);                    //(3).屏幕滑动                    leader = leader + step;                    window.scrollTo(0,leader);                    //(4).清除定时器                    if(Math.abs(target-leader)<=Math.abs(step)){                        window.scrollTo(0,target);                        clearInterval(timer);                    }                },25);            }        }        //4.用scroll事件模拟盒子距离最顶端的距离。        window.onscroll = function () {            //每次屏幕滑动,把屏幕卷去的头部赋值给leader,模拟获取显示区域距离顶部的距离            leader = scroll().top;        }    </script></body></html>

事件对象(event)

再触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象,但支持的方式不同。普通浏览器支持 event(带参,任意参数),ie 678 支持 window.event(无参,内置)。

事件对象的获取(event的获取)

IE678中,window.event,在火狐谷歌中,event或者,在事件绑定的函数中,加参,这个参数就是event。

获取事件的兼容方式

  • 不写参数直接使用event;
  • 写参数,但是为event….var,(主要用这种)
event  = event || window.event;

事件属性

screenX、pageX和clientX的区别

  • PageY/pageX: 鼠标位于整个网页页面的顶部和左侧部分的距离。(页面)
  • ScreenY/screenX: 鼠标位于屏幕的上方和左侧的距离。(屏幕)
  • ClientX/clientY: 鼠标位于浏览器的左侧和顶部的距离。(浏览器大小和位置)

PageY和pageX的兼容写法

在页面位置就等于 = 看得见的+看不见的

pageY/pageX=event.clientY/clientX+scroll().top/scroll().left

onmousemove

onmousemove事件会在鼠标指针移动时发生。

案例

1、需求:当鼠标进入图片,出现细节图。鼠标放到小盒子上,让大盒子里面的图片和我们同步等比例移动。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        * {            margin: 0;            padding: 0;        }        .box {            width: 350px;            height: 350px;            margin:100px;            border: 1px solid #ccc;            position: relative;        }        .big {            width: 400px;            height: 400px;            position: absolute;            top: 0;            left: 360px;            border: 1px solid #ccc;            overflow: hidden;            display: none;        }        .mask {            width: 175px;            height: 175px;            background: rgba(255, 255, 0, 0.4);            position: absolute;            top: 0;            left: 0;            cursor: move;            display: none;        }        .small {            position: relative;        }        img {            vertical-align: top;        }    </style>    <script src="animate.js"></script>    <script>        window.onload = function () {            //技术点:onmouseenter==onmouseover 前者不支持冒泡            //技术点:onmouseleave==onmouseout  前者不支持冒泡                  //0.获取相关元素            var box = document.getElementsByClassName("box")[0];            var small = box.firstElementChild || box.firstChild;            var big = box.children[1];            var mask = small.children[1];            var bigImg = big.children[0];            //1.鼠标放上去显示盒子,移开隐藏盒子。(为小盒子绑定事件)            small.onmouseenter = function () {                //封装好方法调用:显示元素                show(mask);                show(big);            }            small.onmouseleave = function () {                //封装好方法调用:隐藏元素                hide(mask);                hide(big);            }            //2.黄盒子跟随移动            //绑定的事件是onmousemove,而事件源是small(只要在小盒子上移动1像素,黄盒子也要跟随)            small.onmousemove = function (event) {                //想移动黄盒子,必须知道鼠标在small中的位置。x作为mask的left值,y作mask的top值。                event = event || window.event;                var pagex = event.pageX || scroll().left + event.clientX;                var pagey = event.pageY || scroll().top + event.clientY;                //让鼠标在黄盒子最中间,减去黄盒子宽高的一半                var x = pagex - box.offsetLeft - mask.offsetWidth/2;                var y = pagey - box.offsetTop - mask.offsetHeight/2;                //限制换盒子的范围                //left取值为大于0,小盒子的宽-mask的宽。                if(x<0){                    x = 0;                }                if(x>small.offsetWidth-mask.offsetWidth){                    x = small.offsetWidth-mask.offsetWidth;                }                //top同理。                if(y<0){                    y = 0;                }                if(y>small.offsetHeight-mask.offsetHeight){                    y = small.offsetHeight-mask.offsetHeight;                }                //移动黄盒子                console.log(small.offsetHeight);                mask.style.left = x + "px";                mask.style.top = y + "px";                //3.右侧的大图片,等比例移动。                //如何移动大图片?等比例移动。                //    大图片/大盒子 = 小图片/mask盒子                //    大图片走的距离/mask走的距离 = (大图片-大盒子)/(小图片-黄盒子)//              var bili = (bigImg.offsetWidth-big.offsetWidth)/(small.offsetWidth-mask.offsetWidth);                //大图片走的距离/mask盒子都的距离 = 大图片/小图片                var bili = bigImg.offsetWidth/small.offsetWidth;                var xx = bili*x;                var yy = bili*y;                bigImg.style.marginTop = -yy+"px";                bigImg.style.marginLeft = -xx+"px";            }        }    </script></head><body>    <div class="box">        <div class="small">            <img src="images/001.jpg" alt=""/>            <div class="mask"></div>        </div>        <div class="big">            <img src="images/0001.jpg" alt=""/>        </div>    </div></body></html>

2、需求:在指定位置按住鼠标左键移动对话框。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        * {            margin: 0;            padding: 0;        }        .nav {            height: 30px;            background: #036663;            border-bottom: 1px solid #369;            line-height: 30px;            padding-left: 30px;        }        .nav a {            color: #fff;            text-align: center;            font-size: 14px;            text-decoration: none;        }        .d-box {            width: 400px;            height: 300px;            border: 5px solid #eee;            box-shadow: 2px 2px 2px 2px #666;            position: absolute;            top: 40%;            left: 40%;        }        .hd {            width: 100%;            height: 25px;            background-color: #7c9299;            border-bottom: 1px solid #369;            line-height: 25px;            color: white;            cursor: move;        }        #box_close {            float: right;            cursor: pointer;        }    </style>    <script src="animate.js"></script>    <script>        window.onload = function () {            //分析:鼠标按下,触动事件,移动在更换对话框的位置。            //鼠标按下onmousedown   鼠标弹起:onmouseup   鼠标移动onmousemove            var box = document.getElementById("d_box");            var drop = document.getElementById("drop");            //先按下,在移动触动此事件            drop.onmousedown = function (event) {                //获取鼠标在盒子中的坐标,将来移动的时候减去保证鼠标在盒子的指定位置                event = event || window.event;                var pagex = event.pageX || scroll().left + event.clientX;                var pagey = event.pageY || scroll().top + event.clientY;                var x = pagex - box.offsetLeft;                var y = pagey - box.offsetTop;                document.onmousemove = function (event) {                    //2.把鼠标的坐标赋值给对话框。                    event = event || window.event;                    var xx = event.pageX || scroll().left + event.clientX;                    var yy = event.pageY || scroll().top + event.clientY;                    //二次操作鼠标位置  减去鼠标在盒子中的坐标                    xx = xx - x;                    yy = yy - y;                    //给box赋值                    box.style.left = xx+"px";                    box.style.top = yy+"px";                    //禁止文本选中(选中后取消)                    window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();                }            }            //事件解绑            drop.onmouseup = function () {                //解绑                document.onmousemove = null;            }        }    </script></head><body>    <!--顶部注册部分,无用-->    <div class="nav">        <a href="javascript:;" id="register">注册信息</a>    </div>    <!--我们移动的对话框-->    <div class="d-box" id="d_box">        <div class="hd" id="drop">            <i>注册信息 (可以拖拽)</i>            <span id="box_close">【关闭】</span>        </div>        <div class="bd"></div>    </div></body></html>

3、需求:模拟滚动条,鼠标拖动滚动条,滚动条动,而且内容等比例联动。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        * {            margin: 0;            padding: 0;        }        .box {            width: 300px;            height: 500px;            border: 1px solid red;            margin: 50px auto;            overflow: hidden;            position: relative;        }        .scroll {            width: 20px;            height: 530px;            background-color: #ccc;            position: absolute;            top: 0;            right: 0;        }        .bar {            width: 20px;            background-color: red;            border-radius: 10px;            cursor: pointer;            position: absolute;            top: 0;        }        .content {            padding: 15px;        }    </style>    <script src="animate.js"></script>    <script>        window.onload = function () {            //步骤:            //1.根据内容和盒子的比例确定bar的高。            //2.绑定事件(鼠标按下,然后移动)            //3.鼠标移动,bar联动            //4.内容等比例联动            //0.获取相关元素            var box = document.getElementById("box");            var content = box.children[0];            var scroll = box.children[1];            var bar = scroll.children[0];            //1.根据内容和盒子的比例确定bar的高。            //内容的高/盒子的高 = scroll的高/bar的高            //bar的高 = 盒子的高*scroll的高/内容的高            var barHeight = box.offsetHeight*scroll.offsetHeight/content.offsetHeight;            bar.style.height = barHeight + "px";            //2.绑定事件(鼠标按下,然后移动)            bar.onmousedown = function (event) {                event = event || window.event;                var pageyy = event.pageY || scroll().top + event.clientY;                var y = pageyy - bar.offsetTop;                //模拟拖拽案例                document.onmousemove = function (event) {                    //获取鼠标在页面的位置。                    event = event || window.event;                    var pagey = event.pageY || scroll().top + event.clientY;                    //鼠标的位置-鼠标在盒子中的位置。                    pagey = pagey - y;                    //限制y的取值。大于0,小于scroll的高度-bar的高度                    if(pagey<0){                        pagey = 0;                    }                    if(pagey>scroll.offsetHeight-bar.offsetHeight){                        pagey = scroll.offsetHeight-bar.offsetHeight;                    }                    //3.鼠标移动,bar联动                    bar.style.top = pagey + "px";                    //4.内容等比例联动                    //高级比例:  内容走的距离/bar走的距离 = (内容的高-大盒子的高)/(scroll的高-bar的高)                    var s = pagey *(content.offsetHeight-box.offsetHeight)/(scroll.offsetHeight-bar.offsetHeight);                    //s赋值给content。通过marginTop负值移动content                    content.style.marginTop = -s+"px";                    //让被选文字清除。                    window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();                }            }            //事件解绑            document.onmouseup = function () {                document.onmousemove = null;            }        }    </script></head><body>    <div class="box" id="box">        <div class="content">           JavaScript脚本语言具有以下特点:<br>            (1)脚本语言。JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。<br>            (2)基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。<br>            (3)简单。JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。<br>            (4)动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。在访问一个网页时,鼠标在网页中进行鼠标点击或上下移、窗口移动等操作JavaScript都可直接对这些事件给出相应的响应。<br>            (5)跨平台性。JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提上机器上的浏览器支 持JavaScript脚本语言,目前JavaScript已被大多数的浏览器所支持。<br>            不同于服务器端脚本语言,例如PHP与ASP,JavaScript主要被作为客户端脚本语言在用户的浏览器上运行,不需要服务器的支持。所以在早期程序员比较青睐于JavaScript以减少对服务器的负担,而与此同时也带来另一个问题:安全性。            而随着服务器的强壮,虽然程序员更喜欢运行于服务端的脚本以保证安全,但JavaScript仍然以其跨平台、容易上手等优势大行其道。同时,有些特殊功能(如AJAX)必须依赖Javascript在客户端进行支持。随着引擎如V8和框架如Node.js的发展,及其事件驱动及异步IO等特性,JavaScript逐渐被用来编写服务器端程序。<br>        </div>        <div class="scroll">            <div class="bar"></div>        </div>    </div></body></html>

Client

clientWidth & clientHeight

clientWidth 获取网页可视区域宽度
clientHeight 获取网页可视区域高度
两种用法,调用者不同,意义不同:
- 盒子调用: 指盒子本身。
- body/html调用: 可视区域大小。

clientX & clientY

clientX 鼠标距离可视区域左侧距离(event调用)
clientY 鼠标距离可视区域上侧距离(event调用)

clientTop & clientLeft

clientTop和clientLeft分别表示盒子的border宽和高。

Offset、ScrollTo、Client 总结

Width和height

  • clientWidth = width + padding
  • clientHeight = height + padding
  • offsetWidth = width + padding + border
  • offsetHeight = height + padding + border
  • scrollWidth = 内容宽度(不包含border)
  • scrollHeight = 内容高度(不包含border)

top和left

  • offsetTop/offsetLeft :
    • 调用者:任意元素。(盒子为主)
    • 作用:距离父系盒子中带有定位的距离。
  • scrollTop/scrollLeft:(盒子也可以调用,必须有滚动条)
    • 调用者:document.body.scrollTop/…..(window)
    • 作用:浏览器无法显示的部分(被卷去的部分)。
  • clientY/clientX:(clientTop/clientLeft 值的是border)
    • 调用者:event.clientX(event)
    • 作用:鼠标距离浏览器可视区域的距离(左、上)。

Client检浏览器宽/高度(可视区域)

//获取屏幕可视区域的宽高function client(){    if(window.innerHeight !== undefined){        return {            "width": window.innerWidth,            "height": window.innerHeight        }    }else if(document.compatMode === "CSS1Compat"){        return {            "width": document.documentElement.clientWidth,            "height": document.documentElement.clientHeight        }    }else{        return {            "width": document.body.clientWidth,            "height": document.body.clientHeight        }    }}

Onresize事件

浏览器的大小改变时触发。

事件总结

区分:
1. window.onscroll 屏幕滑动
2. window.onresize 浏览器大小变化
3. window.onload 页面加载完毕
4. div.onmousemove 鼠标在盒子上移动
5. onmouseup/onmousedown == onclick

获得屏幕宽高

分辨率是屏幕图像的精密度,指显示器所能显示的像素有多少。

window.screen.width

冒泡

事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。
冒泡:子元素事件被触动,父盒子的同样的事件也会被触动。
取消冒泡就是取消这种机制。

阻止冒泡

  • w3c的方法是:(火狐、谷歌、IE11)
event.stopPropagation()
  • IE10以下则是使用:
event.cancelBubble = true

兼容写法

    //阻止冒泡    event = event || window.event;    if(event && event.stopPropagation){        event.stopPropagation();    }else{        event.cancelBubble = true;    }

addEventListenner

addEventListenner(参数1,参数2,参数3)方法用来绑定事件。
- 调用者是:事件源。
- 参数1:事件去掉on
- 参数2 :调用的函数
- 参数3:可有可无。没有默认false.false情况下,支持冒泡。True支持捕获。

案例

1、需求:点击登录按钮,显示模态框。点击出去login以外的所有盒子隐藏模态框。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        body,html {            height: 100%;            padding: 0;            margin: 0;        }        .mask {            width: 100%;            height: 100%;            position: fixed;            top: 0;            left: 0;            display: none;            background: rgba(0, 0, 0, 0.6);        }        .login {            width: 400px;            height: 300px;            cursor: pointer;            background-color: #fff;            margin: 200px auto;        }    </style></head><body>    <div class="mask">        <div class="login" id="login"></div>    </div>    <a href="#">注册</a>    <a href="#">登陆</a>    <script src="jquery1.0.0.1.js"></script>    <script>        //1.给登录绑定事件        var mask = document.getElementsByClassName("mask")[0];        var a = document.getElementsByTagName("a")[1];        a.onclick = function (event) {            //显示模态框            show(mask);            //阻止冒泡            event = event || window.event;            if(event && event.stopPropagation){                event.stopPropagation();            }else{                event.cancelBubble = true;            }        }        //2.给document绑定事件,因为可以冒泡,只要判断,点击的不是login,那么隐藏模态框        document.onclick = function (event) {            //获取点击按钮后传递过来的值。            event = event || window.event;            //兼容获取事件触动时,被传递过来的对象            var aaa = event.target?event.target:event.srcElement;            console.log(event.target);            //判断目标值的ID是否等于login,如果等于不隐藏盒子,否则隐藏盒子。            if(aaa.id !== "login"){                mask.style.display = "none";            }        }    </script></body></html>

事件委托

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

//普通的事件绑定,没有办法为新创建的元素绑定事件。所以我们要使用冒泡的特性,事件委托ul.onclick = function (event) {    //获取事件触动的时候传递过来的值    event = event || window.event;    var aaa = event.target?event.target:event.srcElement;    //判断标签名,如果是li标签弹窗    if(aaa.tagName === "LI"){        alert("我是li");    }}

缓动框架

获取任意类型的CSS样式的属性值

Div.style.width
div.currentStyle.width
Window.getComputedStyle(div,null).width;
他们的公共使用变量或者字符串获取属性值的方法都是:去电属性和点,然后加上中括号和属性的字符串形式。

var div = document.getElementsByTagName("div")[0];console.log(getStyle(div,"padding"));console.log(getStyle(div,"background-color"));//兼容方法获取元素样式function getStyle(ele,attr){    if(window.getComputedStyle){        return window.getComputedStyle(ele,null)[attr];    }    return ele.currentStyle[attr];}

开闭原则

定义一个变量。数据可以修改。但是,只能修改成为两个值。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        div {            position: absolute;            top: 40px;            left: 10px;            width: 100px;            height: 100px;            background-color: pink;        }    </style></head><body>    <button>运动到400</button>    <div></div>    <script>        var btnArr = document.getElementsByTagName("button");        var div = document.getElementsByTagName("div")[0];        btnArr[0].onclick = function () {            var json = {"left":10,"top":200,"width":300,"height":200};            animate(div,json);        }        //参数变为3个        function animate(ele,json){            //先清定时器            clearInterval(ele.timer);            ele.timer = setInterval(function () {                //开闭原则                var bool = true;                //遍历属性和值,分别单独处理json                //attr == k(键)    target == json[k](值)                for(var k in json){                    //四部                    var leader = parseInt(getStyle(ele,k)) || 0;                    //1.获取步长                    var step = (json[k] - leader)/10;                    //2.二次加工步长                    step = step>0?Math.ceil(step):Math.floor(step);                    leader = leader + step;                    //3.赋值                    ele.style[k] = leader + "px";                    //4.清除定时器                    //判断: 目标值和当前值的差大于步长,就不能跳出循环                    //不考虑小数的情况:目标位置和当前位置不相等,就不能清除清除定时器。                    if(json[k] !== leader){                        bool = false;                    }                }                //只有所有的属性都到了指定位置,bool值才不会变成false;                if(bool){                    clearInterval(ele.timer);                }            },25);        }        //兼容方法获取元素样式        function getStyle(ele,attr){            if(window.getComputedStyle){                return window.getComputedStyle(ele,null)[attr];            }            return ele.currentStyle[attr];        }    </script></body></html>

回调函数

程序执行完毕,在次执行的函数。
在函数中给指定的函数定义一个形参,然后程序执行到最后,调用这个形参后面加一个括号。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <style>        div {            position: absolute;            top: 40px;            left: 10px;            width: 100px;            height: 100px;            background-color: pink;        }    </style></head><body>    <button>运动到400然后回来</button>    <div></div>    <script>        var btnArr = document.getElementsByTagName("button");        var div = document.getElementsByTagName("div")[0];        btnArr[0].onclick = function () {            var json1 = {"left":300,"top":200,"width":300,"height":200};            var json2 = {"left":10,"top":30,"width":100,"height":100};            animate(div,json1, function () {                animate(div,json2, function () {                    animate(div,json1);                });            });        }        //参数变为3个        function animate(ele,json,fn){            //先清定时器            clearInterval(ele.timer);            ele.timer = setInterval(function () {                //开闭原则                var bool = true;                //遍历属性和值,分别单独处理json                //attr == k(键)    target == json[k](值)                for(var k in json){                    //四部                    var leader = parseInt(getStyle(ele,k)) || 0;                    //1.获取步长                    var step = (json[k] - leader)/10;                    //2.二次加工步长                    step = step>0?Math.ceil(step):Math.floor(step);                    leader = leader + step;                    //3.赋值                    ele.style[k] = leader + "px";                    //4.清除定时器                    //判断: 目标值和当前值的差大于步长,就不能跳出循环                    //不考虑小数的情况:目标位置和当前位置不相等,就不能清除清除定时器。                    if(json[k] !== leader){                        bool = false;                    }                }                //只有所有的属性都到了指定位置,bool值才不会变成false;                if(bool){                    clearInterval(ele.timer);                    //所有程序执行完毕了,现在可以执行回调函数了                    //只有传递了回调函数,才能执行                    if(fn){                        fn();                    }                }            },25);        }        //兼容方法获取元素样式        function getStyle(ele,attr){            if(window.getComputedStyle){                return window.getComputedStyle(ele,null)[attr];            }            return ele.currentStyle[attr];        }    </script></body></html>

案例

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title>旋转木马轮播图</title>    <link rel="stylesheet" href="css/css.css"/>    <script src="js/jquery1.0.0.1.js"></script>    <script src="js/js.js"></script></head><body>    <div class="wrap" id="wrap">       <div class="slide" id="slide">           <ul>               <!--五张图片-->               <li><a href="#"><img src="images/slidepic1.jpg" alt=""/></a></li>               <li><a href="#"><img src="images/slidepic2.jpg" alt=""/></a></li>               <li><a href="#"><img src="images/slidepic3.jpg" alt=""/></a></li>               <li><a href="#"><img src="images/slidepic4.jpg" alt=""/></a></li>               <li><a href="#"><img src="images/slidepic5.jpg" alt=""/></a></li>           </ul>           <!--左右切换按钮-->           <div class="arrow" id="arrow">               <a href="javascript:;" class="prev"></a>               <a href="javascript:;" class="next"></a>           </div>       </div>    </div></body></html>
window.onload = function () {    var arr = [        {   //  1            width:400,            top:70,            left:50,            opacity:20,            zIndex:2        },        {  // 2            width:600,            top:120,            left:0,            opacity:80,            zIndex:3        },        {   // 3            width:800,            top:100,            left:200,            opacity:100,            zIndex:4        },        {  // 4            width:600,            top:120,            left:600,            opacity:80,            zIndex:3        },        {   //5            width:400,            top:70,            left:750,            opacity:20,            zIndex:2        }    ];    //0.获取元素    var slide = document.getElementById("slide");    var liArr = slide.getElementsByTagName("li");    var arrow = slide.children[1];    var arrowChildren = arrow.children;    //设置一个开闭原则变量,点击以后修改这个值。    var flag = true;    //1.鼠标放到轮播图上,两侧的按钮显示,移开隐藏。    slide.onmouseenter = function () {        //arrow.style.opacity = 1;        animate(arrow,{"opacity":100});    }    slide.onmouseleave = function () {        //arrow.style.opacity = 1;        animate(arrow,{"opacity":0});    }    move();    //3.把两侧按钮绑定事件。(调用同一个方法,只有一个参数,true为正向旋转,false为反向旋转)    arrowChildren[0].onclick = function () {        if(flag){            flag = false;            move(true);        }    }    arrowChildren[1].onclick = function () {        if(flag){            flag = false;            move(false);        }    }    //4.move函数    function move(bool){        //判断:如果等于undefined,那么就不执行这两个if语句        if(bool === true || bool === false){            if(bool){                arr.unshift(arr.pop());            }else{                arr.push(arr.shift());            }        }        //在次为页面上的所有li赋值属性,利用缓动框架        for(var i=0;i<liArr.length;i++){            animate(liArr[i],arr[i], function () {                flag = true;            });        }    }}