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閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容