06-JS特效-01三大系列和事件

一、三大系列:offset家族、scroll家族、client

1、offset

1.1.简介
  • offset家族就是js中一套方便获取元素尺寸的方法;
  • offset常用属性:offsetWidth和offsetHeight;offsetLeft和offsetTop;offsetParent。
1.2.offsetWidth和offsetHeight:
  • 可以检测盒子的宽高,没有单位,是number类型;
  • 包括盒子宽高本身、padding、border;
  • offsetHeight = height + padding + border;(不包括margin);
  • offsetWidth = width + padding + border;(不包括margin);
1.3.offsetLeftoffsetTop检测距离有定位的父系盒子左/上的距离):
  • 返回距离上级盒子(带有定位)左边/上面的距离;

  • 如果父级都没有定位则以body为准;

  • offsetLeft从父盒子的padding开始算(包含父盒子的padding),父盒子的border不算;

  • 在父盒子有定位的情况下,offsetLeft 不一定等于 style.left(去掉单位px),如果给style.left(只识别行内)赋值了,将style.left单位去掉会相等;如果没有赋值的话就不会相等。

  • offsetLeft和style.left的区别:

    • 最大的区别在于offsetLeft可以返回没有定位盒子距离左侧的位置;如果父系盒子中都没有定位,以body为准;style.left只能获取行内式,如果没有就返回"";
    • offsetLeft返回的是数字,而style.left返回是带有px的字符串;
    • offsetLeft只读,一般用来取值,而style.left可读写,一般用来赋值;
    • 如果没有给HTML元素行内指定过left样式,则style.left返回的是空字符串。
1.4.offsetParent(检测父盒子中带有定位的父盒子节点)
  • 返回该对象的父级(带有定位),如果父系盒子中都没有进行CSS定位(position为absolute、relative或fixed),offsetParent为body
  • 如果当前元素的父级有CSS定位,就返回最近的那个父级元素;
  • 除了static之外的其它定位。

2.第二系列scroll

2.1.Scroll家族组成:ScrollWidth和scrollHeightscrollTop和scrollLeft
2.2. ScrollWidth和scrollHeight(不包括border)
  • 检测盒子的宽高:节点元素.属性,内容没有超出盒子时,值为盒子宽高;

  • 盒子内容的宽高:如果有内容超出盒子高度,显示内容的高度;

  • IE567可以比盒子小;IE8+火狐谷歌不能比盒子小。

  • scrollWidth = width + padding

  • 介绍一下新事件:onscroll

  • onscroll滚动事件:屏幕每滚动一次,哪怕只有1像素都会触发这个事件。这样就可以用来检测屏幕滚动了;但是只能有一个此事件,如果有多个以最后一个为准,同window.onload

window.onscroll = function (){};
2.3. scrollTop和scrollLeft
  • 网页,被浏览器遮挡的头部和左边部分;

  • 被卷去的头部和左边部分。

  • 它有兼容性问题

  • 未声明 DTD(谷歌只认识body):

document.body.scrollTop
  • 已经声明DTD(一些老版本的兼容性问题,IE678只认识documentElement):
document.documentElement.scrollTop
  • 火狐/谷歌/ie9+以上支持的(不管DTD):
window.pageYOffset
  • 兼容写法
var aaa = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;

或者

var aaa = document.documentElement.scrollTop + document.body.scrollTop;
2.4.获取title、body、head、html标签
  • document.title --- 文档标题;
  • document.head --- 文档的头标签
  • document.body --- 文档的body标签;
  • document.documentElement --- 这个很重要,它表示文档的html标签, 也就是说,基本结构当中的html标签并不是通过document.html去访问的,而是document.documentElement
2.5.Json
  • Json是一种和数组类似的数据类型;
  • 不同的是:数组中的元素是单一的;
  • 而json中的元素,是以键值对的形式出现的。(key: value)
2.5.1.定义方法
var  json  =  { key1:value1,key2:value2,key3:value3...  };
  • 数组是通过索引值获取数组中的元素的,而json是通过key获取元素的。
2.5.2.获取内容
  • JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,我们称之为JavaScript对象表示法。使用JSON进行数据传输的优势之一。表示方法为键值对,key:value。
  • var myjson={k1:v1,k2:v2,k3:v3...}
    ,获取方式:v1 == myjson.k1 ; v2 == myjson.k2;
  • Json一般就是被当做一个配置单用。
2.5.3.Json的遍历(了解)
  • 用的语法方法:for...in...
<script>
    var json = {"aaa":111,"bbb":222};
    for (var k in json){
        console.log(k);
        console.log(json[k]);
    }
</script>
//打印的结果为:
//aaa
//111
//bbb
//222
2.6.判断页面有没有DTD

document.compatMode === "BackCompat"

BackCompat  未声明
CSS1Compat  已经声明
  • 注意大小写。
2.7.scroll()函数的封装
  • 需求:封装一个兼容的scroll()方法,返回值是JSON,用scroll().top获取scrollTop。
<script>
    //var json = scroll();
    //console.log(json.top);
    //console.log(json.left);
    console.log(scroll().top);
    console.log(scroll().left);

    function scroll(){
        //如果window.pageYOffset存在,返回值为0~无穷大,如果不存在返回undefined。
        if (window.pageYOffset !== undefined){
            var json = {
                "top":window.pageYOffset,
                "left":window.pageXOffset
            }
        } else if (document.compatMode === CSS1Compat) {
            return {
                "top":document.documentElement.scrollTop,
                "left":document.documentElement.scrollLeft
            }
        } else {
            return {
                "top":document.body.scrollTop,
                "left":document.body.scrollLeft
            }
        }
    }
</script>

简单版:

<script>
    function scroll(){
        //如果window.pageYOffset存在,返回值为0~无穷大,如果不存在返回undefined。
        return {
            "top":window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop,
            "left":window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft
        }
    }
</script>
  • 练习:
    • 固定导航栏;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>固定导航栏</title>

    <style>
        *{
            margin: 0;
            padding: 0;
        }

        img{
            vertical-align: top;
        }
        .main{
            width: 1000px;
            margin: 10px auto;
        }

        .fix{
            position: fixed;
            top: 0;
            left: 0;
        }

    </style>

</head>
<body>
    <div class="top">
        ![](images/top.png)
    </div>
    <div class="nav">
        ![](images/nav.png)
    </div>
    <div class="main">
        ![](images/main.png)
    </div>

    <script>
        window.onload = function () {
            var top = document.getElementsByClassName("top")[0];
            var topHeight = top.offsetHeight;
            var middle = document.getElementsByClassName("nav")[0];
            var main = document.getElementsByClassName("main")[0];

            window.onscroll = function () {
                if (scroll().top >= topHeight){
                    middle.className = "fix";
                    main.style.padding = middle.offsetHeight + "px";
                }else {
                    middle.className = "";
                    main.style.padding = 0;
                }
            }

            function scroll() {
                return {
                    "top" : window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop,
                    "left" : window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft
                }
            }
        }
    </script>
</body>
</html>
  • 两侧跟随的广告;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>固定导航栏</title>

    <style>
        .img1{
            position: absolute;
            top: 80px;
            left: 6px;
        }
        .img2{
            position: absolute;
            top: 80px;
            right: 6px;
        }
        div{
            width: 600px;
            margin: 20px auto;
            font-size: 20px;
            line-height: 50px;
            color: red;
        }
    </style>

    <script src="../Yijiang.js"></script>
    <script>
        window.onload = function () {
            var img1 = document.getElementsByClassName("img1")[0];
            var img2 = document.getElementsByClassName("img2")[0];

            window.onscroll = function () {
                slowMovingAnimateY(img1,scroll().top + 80);
                slowMovingAnimateY(img2,scroll().top + 80);
            }
        }
    </script>
</head>
<body>
    ![](images/aside.jpg)
    ![](images/aside.jpg)
    <div class="content">
        我是第一行。。。<br>
        你我是永相随,醉把佳人成双对。。。<br>
        你我是永相随,醉把佳人成双对。。。<br>
        //上面的内容加到三四十行
    </div>
</body>
</html>
  • 小火箭返回头部。
    • 技术点:window.scrollTo(x,y);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>固定导航栏</title>

    <style>
        *{
            margin: 0;
            padding: 0;
        }

        .img{
            position: fixed;
            right: 150px;
            bottom: 150px;
            display: none;
        }
        .content{
            width: 600px;
            font: italic 700 26px/40px "Simhei";
            color: red;
            margin: 0 auto;
        }
    </style>

    <script src="../Yijiang.js"></script>
    <script>
        window.onload = function () {
            var fire = document.getElementsByClassName("img")[0];

            window.onscroll = function () {
                if (scroll().top > 200){
                    fire.style.display = "block";
                }else {
                    fire.style.display = "none";
                }

                position = scroll().top;
            };

            var target = 0; //目标位置
            var position = 0;   //目前显示位置
            var timer = null;   //成员变量就是window的属性
            fire.onclick = function () {
                //使用定时器之前先清除定时器
                clearInterval(timer);
                timer = setInterval(function () {
                    //计算步长
                    var step = (target - position) / 10;
                    step = step>0 ? Math.ceil(step):Math.floor(step);
                    //动画原理
                    position = position + step;
                    //运动到当前目标位置
                    window.scrollTo(0,position);
                    if (target == position){
                        clearInterval(timer);
                    }
                },25);
            };
        };
    </script>
</head>
<body>
    ![](images/Top.jpg)
    <div class="content">
        我是第一行。。。<br>
        你我是永相随,醉把佳人成双对。。。<br>
        你我是永相随,醉把佳人成双对。。。<br>
        //上面的内容加到三四十行
    </div>
</body>
</html>
  • 楼层跳跃。
    • 100%:宽高设置为此值,可以使子盒子继承父盒子的宽高;可以使父盒子继承body的宽高;可以使body继承html的宽高。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>电商楼层跳跃</title>

    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body,html{
            height: 100%;
        }

        ul{
            height: 100%;
            list-style: none;
        }
        ul li{
            height: 100%;
        }
        ol{
            position: fixed;
            left: 20px;
            top: 100px;
            list-style: none;
        }
        ol li{
            border: 1px solid #000;
            height: 50px;
            width: 65px;
            line-height: 50px;
            text-align: center;
            font-size: 20px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <ul class="detail">
        <li>男士专区</li>
        <li>女士专区</li>
        <li>儿童专区</li>
        <li>婴儿物品</li>
        <li>中老年营养品</li>
    </ul>

    <ol class="summary">
        <li>男士</li>
        <li>女士</li>
        <li>儿童</li>
        <li>婴儿</li>
        <li>中老年</li>
    </ol>

    <script src="../Yijiang.js"></script>
    <script src="../jquery-1.11.1.min.js"></script>
    <script>
        window.onload = function () {
            var ul = document.getElementsByClassName("detail")[0];
            var ol = document.getElementsByClassName("summary")[0];
            var ulArr = ul.children;
            var olArr = ol.children;

            var height = ulArr[0].offsetHeight;
            var colorArr = ["#9a2","pink","orange","#0a2","#f44"];

            var timer = null;
            var target = 0;
            var position = 0;

            for(var i=0; i<olArr.length; i++){
                olArr[i].index = i;
                ulArr[i].style.backgroundColor = colorArr[i];
                olArr[i].style.backgroundColor = colorArr[i];

                olArr[i].onclick = function () {
                    position = scroll().top;
                    target = ulArr[this.index].offsetTop;

                    clearInterval(timer);
                    var timer = setInterval(function () {
                        var step = (target - position) / 10;
                        step = step>0 ? Math.ceil(step):Math.floor(step);
                        position = position + step;
                        window.scrollTo(0,position);
                        if (Math.abs(target-position)<=Math.abs(step)){
                            clearInterval(timer);
                        }
                    },15);
                }
            }
        };
    </script>
</body>
</html>

3.第三大家族client

3.1.主要成员:clientWidth/clientHeightclientX/clientYclientTop/clientLeft
  • clientWidth:获取网页可视区域宽度(两种用法);clientHeight:获取网页可视区域高度(两种用法),调用者不同,意义不同

  • 盒子调用:指盒子本身(不包括border,clientWidth = padding + width);

  • body/html调用:可视区域大小。

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

  • clientTop/clientLeft:盒子的border宽高。

3.2.三大家族区别(三大家族总结)
  • Width和height

  • clientWidth = width + padding(盒子/body、html可视区域大小);

  • clientHeight = height + padding(盒子/body、html可视区域大小);

  • 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)
    • 嘛作用:鼠标距离浏览器可视区域的距离(左、上)。
3.3.client家族特殊用法之:检浏览器宽/高度(可视区域)
  • IE9及其以上的版本:window.innerWidth/Height;,替代clientWidth/clientHeight;
  • 标准模式(有DTD)("CSS1Compat"):document.documentElement.clientWidth;
  • 怪异模式(没有DTD):document.body.clientWidth;
  • 封装:类似scroll();,但是不可有"+"的形式,因为用这里的获取方式进行获取时,如果没有获取到可能会报错。
3.4.onresize事件
  • 只要浏览器的大小改变,哪怕1像素,都会触动这个事件window.onresize = function(){};

  • 案例:根据浏览器可视区域大小,给定背景色。

  • 模拟响应式:移动版(640)/ 平板 / PC版(960)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>根据浏览器窗口大小改变背景色</title>
</head>
<body>

    <script>
        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
                }
            }
        }

        window.onresize = showColor();
        showColor();//初始时,窗口大小没有变动时,也给浏览器上背景色

        function showColor() {
            if (client().width >= 960){
                document.body.style.backgroundColor = "#a00";
            }else if (client().width >= 640){
                document.body.style.backgroundColor = "#0a0";
            }else{
                document.body.style.backgroundColor = "#00a";
            }
        }
    </script>
</body>
</html>
3.5事件总结
  • 区分:
事件 说明
window.onscroll 屏幕滑动
window.onresize 浏览器大小变化
window.onload 页面加载完毕
div.onmousemove 鼠标在盒子上移动(注意:不是盒子移动!!!)
onmouseup/onmousedown onclick
3.6.获得屏幕宽高
  • window.screen.width
  • 分辨率是屏幕图像的精密度,指显示器所能显示的像素有多少。
  • 我们的电脑一般:横向1280个像素点,纵向960个像素点。我们看电影的时候是满屏和半屏的,就是这。

4.事件对象(event)

  • 在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象,但支持的方式不同。
    比如鼠标操作时候,会添加鼠标位置的相关信息到事件对象中。(类似Date)
    普通浏览器支持 event(带参,任意参数);ie 678 支持 window.event(无参,内置)。
    总结:它是一个事件中的内置对象。内部装了很多关于鼠标和事件本身的信息。
4.1.事件对象的获取(event的获取)
  • IE678中,window.event
<script>
    window.onload = function (){
        var div1 = document.getElementsByClassName("content")[0];
        div1.onclick = function (){
            console.log(event);
            console.log(window.event);
            //两个打印的结果一样
        }
    }
</script>
  • 在火狐谷歌中,event或者在事件绑定的函数中加参,这个参数就是event。
Box.onclick = function (aaa){
        console.log(event);
        console.log(aaa);
}
  • 兼容获取方式有两种:
  • 不写参数直接使用event;
  • 写参数,参数为event,兼容性写法var event = event || window.event;(主要用这种)
4.2.event内容重要内容
属性 作用
timeStamp 返回事件生成的日期和时间
<span style="color:#0aa">bubbles 返回布尔值,指示事件是否是起泡事件类型
button 返回当事件被触发时,哪个鼠标按钮被点击了
<span style="color:red">pageX 光标相对于该网页的水平位置(IE678无)
<span style="color:red">pageY 光标相对于该网页的垂直位置(IE678无)
<span style="color:red">screenX 光标相对于该屏幕的水平位置
<span style="color:red">screenY 光标相对于该屏幕的垂直位置
target 该事件被传送到的对象
type 事件的类型
<span style="color:red">clientX 光标相对于该网页的水平位置(当前可见区域)
<span style="color:red">clientY 光标相对于该网页的垂直位置
  • 相关比较:
  • PageY/pageX: 鼠标距离整个网页页面的顶部和左侧部分的距离。(页面)
  • ScreenY/screenX: 鼠标距离屏幕的上方和左侧的距离。(屏幕)
  • ClientX/clientY: 鼠标距离浏览器的左侧和顶部的距离。(浏览器大小和位置)
4.3.PageY和pageX的兼容写法很重要
  • 在页面位置就等于 = 看得见的+看不见的pageY/pageX=event.clientY/clientX+scroll().top/scroll().left;;(其中scroll()为上面自己封装的函数)

  • 案例:鼠标跟随。有位置移动的都需要定位

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>鼠标跟随</title>

    <style>
        img{
            position: absolute;
            width: 100px;
            height: 100px;
            border: 1px solid #000;
        }
    </style>
</head>
<body>

    <div>
        ![](images/img.jpg)
    </div>

    <script src="../Yijiang.js"></script>
    <script>
        window.onload = function () {
            //获取事件源和相关标签
            var img = document.getElementsByTagName("img")[0];

            //初始化一些数据
            var timer = null;
            var positionX = 0,positionY = 0;
            var targetX = 0,targetY = 0;

            document.onclick = function (event) {
                //获取事件
                event = event || window.event;

                //获取鼠标点击的位置,为了让鼠标停留在图片中间,最后再减去图片宽度的一半
                targetX = (event.pageX || event.clientX + scroll().left) - img.offsetWidth/2;
                targetY = (event.pageY || event.clientY + scroll().top) - img.offsetHeight/2;

                //获取图片初始状态位置
                positionX = img.offsetLeft;
                positionY = img.offsetTop;

                timer = setInterval(function () {
                    //计算步长
                    var stepX = (targetX - positionX) / 10;
                    stepX = stepX>0 ? Math.ceil(stepX):Math.floor(stepX);
                    //动画原理
                    positionX = positionX + stepX;
                    img.style.left = positionX + "px";

                    var stepY = (targetY - positionY) / 10;
                    stepY = stepY>0 ? Math.ceil(stepY):Math.floor(stepY);
                    positionY = positionY + stepY;
                    img.style.top = positionY + "px";

                    //清除定时器
                    if (Math.abs(targetX - positionX)<=Math.abs(stepX) && Math.abs(targetY - positionY)<=Math.abs(stepY)){
                        img.style.top = targetY + "px";
                        img.style.legt = targetX + "px";
                        clearInterval(timer);
                    }
                },30)
            }
        }
    </script>
</body>
</html>
4.4.新事件(onmousemove)
  • 只要鼠标在绑定该事件的事件源上移动,哪怕1像素,也会触动这个事件。
  • 这个事件可以直接或者间接的替代定时器
  • 案例:鼠标在盒子中的坐标。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>鼠标在盒子中的位置</title>

    <style>
        div{
            width: 300px;
            height: 200px;
            padding-top: 100px;
            background-color: pink;
            margin: 100px;
            text-align: center;
            font: 20px/30px "Simsun";
        }
    </style>

</head>
<body>
    <div></div>

    <script>
        window.onload = function () {
            var div = document.getElementsByTagName("div")[0];

            //当鼠标在盒子上移动时触发事件
            div.onmousemove = function (event) {
                event = event || window.event;

                //获取鼠标所处的位置
                var x = event.pageX || event.clientX + scroll().left;
                var y = event.pageY || event.clientY + scroll().top;

                //获取盒子所处的位置
                var divX = div.offsetLeft;
                var divY = div.offsetTop;

                //获取鼠标在盒子中的位置
                var positionX = x - divX;
                var positionY = y - divY;

                div.innerHTML = "盒子中鼠标的X坐标为:" + positionX +"px" + "<br>" + "盒子中鼠标的Y坐标为:" + positionY +"px";
            };

            //当鼠标离开盒子时,清空内容
            div.onmouseout = function () {
                div.innerHTML = "";
            }
        }
    </script>
</body>
</html>
案例
  • 放大镜
  • 注意1:CSS部分要注意:大图片/大盒子 = 小图片/显示部分
  • 注意2:(大图片/大盒子 = 小图片/黄盒子)
    大盒子滑动的距离/小盒子滑动的距离 = 大盒子滑倒头/小盒子滑倒头
    大盒子滑倒头/小盒子滑倒头(他们的距离如何获取呢?)
    (大图片-大盒子)(两边各有一伴儿大盒子的距离是没有走的)
    (小盒子-小图片)(两边各有一伴儿小盒子的距离是没有走的)
  • 注意3:
    onmouseover、onmouseout事件给定一个盒子,子元素也会获取这个事件。
    替代方法:onmosueenter和onmouseleave(此方法不冒泡).
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>放大镜</title>

    <style>
        *{
            padding: 0;
            margin: 0;
        }
        .content{
            width: 300px;
            height: 300px;
            margin-top: 80px;
            margin-left: 160px;
            position: relative;
            border: 1px solid #000;
        }
        .small{
            position: relative;
        }
        .small img{
            width: 300px;
            height: 300px;
        }
        .small .scan{
            height: 150px;
            width: 150px;
            background-color: rgba(200,200,0,0.6);
            position: absolute;
            top: 0;
            left: 0;
            display: none;
        }

        .big{
            width: 400px;
            height: 400px;
            border: 1px solid #000;
            position: absolute;
            left: 340px;
            top: 0;
            overflow: hidden;
            display:none;
        }
    </style>
</head>
<body>
    <div class="content">
        <div class="small">
            ![](images/001.jpg)
            <div class="scan"></div>
        </div>
        <div class="big">
            ![](images/0001.jpg)
        </div>
    </div>

    <script>
        window.onload = function () {
            //显示相关元素
            var content = document.getElementsByClassName("content")[0];
            var small = content.children[0];
            var big = content.children[1];
            var scan = small.children[1];
            var bigImg = big.children[0];

            //鼠标进入,遮盖和大图显示框显示
            small.onmouseenter = function () {
                big.style.display = "block";
                scan.style.display = "block";
            };
            //鼠标离开,遮盖和大图显示框隐藏
            small.onmouseleave = function () {
                big.style.display = "none";
                scan.style.display = "none";
            };

            //绑定鼠标移动事件
            small.onmousemove = function (event) {
                //获取鼠标的位置
                event = event || window.event;
                var pagex = event.pageX || event.clientX + scroll().left;
                var pagey = event.pageY || event.clientY + scroll().top;
                //获取鼠标在盒子中的位置(pagex - content.offsetLeft),并让鼠标处在遮盖中间位置
                var positionX = pagex - content.offsetLeft - scan.offsetWidth / 2;
                var positionY = pagey - content.offsetTop - scan.offsetHeight / 2;
                //判断遮盖的位置,不让其超出盒子的范围
                if (positionX<=0){
                    positionX = 0;
                }
                if (positionX >= content.offsetWidth - scan.offsetWidth){
                    positionX = content.offsetWidth - scan.offsetWidth;
                }
                if (positionY <= 0){
                    positionY = 0;
                }
                if (positionY >= content.offsetHeight - scan.offsetHeight){
                    positionY = content.offsetHeight - scan.offsetHeight;
                }
                //把算好的位置赋值给遮盖
                scan.style.left = positionX + "px";
                scan.style.top = positionY + "px";

                //按比例算大图应该显示的位置:遮盖位置的X/小图宽=大图显示位置的X/大图宽
                var bigShowX = scan.offsetLeft / small.offsetWidth * bigImg.offsetWidth;
                var bigShowY = scan.offsetTop / small.offsetHeight * bigImg.offsetHeight;
                //确定大图显示位置
                bigImg.style.left = - bigShowX + "px";
                bigImg.style.top = - bigShowY + "px";
            }
        };

        //封装scroll()
        function scroll() {
            return{
                "top":window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop,
                "left":window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft
            }
        }
    </script>
</body>
</html>
  • 拖拽案例
    • 禁止文本选中(选中后取消)
window.getSelection() ? window.getSelection().removeAllRanges():document.selection.empty("");
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>拖拽案例</title>

    <style>
        .register{
            width: 320px;
            height: 260px;
            position: absolute;
            border: 3px solid #ddd;
            top: 20%;
            left: 20%;
        }

        .hd{
            height: 30px;
            background-color: #096;
            font: 20px/30px "Simsun";
            cursor: move;
        }
        .close{
            float: right;
            cursor: pointer;
        }
    </style>

</head>
<body>

    <div class="register">
        <div class="hd">
            <em>注册信息(可以拖拽)</em>
            <span class="close">【关闭】</span>
        </div>
    </div>

    <script>
        //入口函数
        window.onload = function () {
            //获取事件源和相关元素
            var register = document.getElementsByClassName("register")[0];
            var hd = register.firstElementChild || register.firstChild;

            //给鼠标按下时绑定事件
            hd.onmousedown = function (event) {
                //获取鼠标的位置
                event = event || window.event;
                var pagex = window.pageX || event.clientX + scrolll().left;
                var pagey = window.pageY || event.clientY + scrolll().left;
                //获取鼠标在盒子中的位置
                var positionX = pagex - register.offsetLeft;
                var positionY = pagey - register.offsetTop;

                //给鼠标移动绑定事件
                document.onmousemove = function (event) {
                    //获取鼠标位置
                    event = event || window.event;
                    var mouseX = window.pageX || event.clientX + scrolll().left;
                    var mouseY = window.pageY || event.clientY + scrolll().left;
                    //用鼠标位置减去鼠标在盒子中的位置就是盒子要移动到的位置
                    register.style.left = mouseX - positionX + "px";
                    register.style.top = mouseY - positionY + "px";

                    //取消选中
                    window.getSelection() ? window.getSelection().removeAllRanges():document.selection.empty("");
                };
            };

            //鼠标抬起时解绑事件
            hd.onmouseup = function () {
                document.onmousemove = null;
            };

            function scrolll() {
                return{
                    "top":window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop,
                    "left":window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft
                }
            }
        }
    </script>

</body>
</html>
  • 模拟滚动条

事件被触动时,鼠标和键盘的状态
通过属性控制

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容