JavaScript十 - 元素(PC網頁特效)

13.1 元素偏移量offset系列

13.1.1 offset 概述

offset 翻譯過來就是偏移量, 我們使用 offset系列相關屬性可以動態的得到該元素的位置(偏移)、大小等

  1. 獲得元素距離帶有定位父元素的位置
  2. 獲得元素自身的大小(寬度高度)
  3. 注意:返回的數值都不帶單位



代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .father {
            /* position: relative; */
            width: 200px;
            height: 200px;
            background-color: pink;
            margin: 150px;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: purple;
            margin-left: 45px;
        }
        .w {
            height: 200px;
            background-color: skyblue;
            margin: 0 auto 200px;
            padding: 10px;
            border: 15px solid red;
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <div class="w"></div>
    <script>
        // offset 系列
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        // 1.可以得到元素的偏移 位置 返回的不帶單位的數值  
        console.log(father.offsetTop);
        console.log(father.offsetLeft);
        // 它以帶有定位的父親爲準  如果麼有父親或者父親沒有定位 則以 body 爲準
        console.log(son.offsetLeft);
        var w = document.querySelector('.w');
        // 2.可以得到元素的大小 寬度和高度 是包含padding + border + width 
        console.log(w.offsetWidth);
        console.log(w.offsetHeight);
        // 3. 返回帶有定位的父親 否則返回的是body
        console.log(son.offsetParent); // 返回帶有定位的父親 否則返回的是body
        console.log(son.parentNode); // 返回父親 是最近一級的父親 親爸爸 不管父親有沒有定位
    </script>
</body>
</html>

13.1.2 offset 與 style 區別

offset:

  • offset 可以得到任意樣式表中的樣式值

  • offset 系列獲得的數值是沒有單位的

  • offsetWidth 包含padding+border+width

  • offsetWidth 等屬性是隻讀屬性,只能獲取不能賦值

  • 所以,我們想要獲取元素大小位置,用offset更合適

style:

  • style 只能得到行內樣式表中的樣式值

  • style.width 獲得的是帶有單位的字符串

  • style.width 獲得不包含padding和border 的值

  • style.width 是可讀寫屬性,可以獲取也可以賦值

  • 所以,我們想要給元素更改值,則需要用style改變

因爲平時我們都是給元素註冊觸摸事件,所以重點記住 targetTocuhes

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: pink;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div class="box" style="width: 200px;"></div>
    <script>
        // offset與style的區別
        var box = document.querySelector('.box');
        console.log(box.offsetWidth);
        console.log(box.style.width);
        // box.offsetWidth = '300px';
        box.style.width = '300px';
    </script>
</body>

</html>

13.1.3 案例講解-獲取鼠標在盒子內的座標

思路:

  1. 我們在盒子內點擊,想要得到鼠標距離盒子左右的距離。
  2. 首先得到鼠標在頁面中的座標(e.pageX, e.pageY)
  3. 其次得到盒子在頁面中的距離 ( box.offsetLeft, box.offsetTop)
  4. 用鼠標距離頁面的座標減去盒子在頁面中的距離,得到 鼠標在盒子內的座標
  5. 如果想要移動一下鼠標,就要獲取最新的座標,使用鼠標移動

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 300px;
            height: 300px;
            background-color: pink;
            margin: 200px;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script>
        // 我們在盒子內點擊, 想要得到鼠標距離盒子左右的距離。
        // 首先得到鼠標在頁面中的座標( e.pageX, e.pageY)
        // 其次得到盒子在頁面中的距離(box.offsetLeft, box.offsetTop)
        // 用鼠標距離頁面的座標減去盒子在頁面中的距離, 得到 鼠標在盒子內的座標
        var box = document.querySelector('.box');
        box.addEventListener('mousemove', function(e) {
            // console.log(e.pageX);
            // console.log(e.pageY);
            // console.log(box.offsetLeft);
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;
            this.innerHTML = 'x座標是' + x + ' y座標是' + y;
        })
    </script>
</body>
</html>

13.1.4 案例講解-模態框拖拽

彈出框,我們也稱爲模態框

  1. 點擊彈出層,會彈出模態框, 並且顯示灰色半透明的遮擋層
  2. 點擊關閉按鈕,可以關閉模態框,並且同時關閉灰色半透明遮擋層
  3. 鼠標放到模態框最上面一行,可以按住鼠標拖拽模態框在頁面中移動
  4. 鼠標鬆開,可以停止拖動模態框移動

思路:

  1. 點擊彈出層, 模態框和遮擋層就會顯示出來 display:block;
  2. 點擊關閉按鈕,模態框和遮擋層就會隱藏起來 display:none;
  3. 在頁面中拖拽的原理:鼠標按下並且移動, 之後鬆開鼠標
  4. 觸發事件是鼠標按下mousedown,鼠標移動mousemove 鼠標鬆開 mouseup
  5. 拖拽過程: 鼠標移動過程中,獲得最新的值賦值給模態框的left和top值,這樣模態框可以跟着鼠標走了
  6. 鼠標按下觸發的事件源是最上面一行,就是 id 爲 title
  7. 鼠標的座標減去 鼠標在盒子內的座標, 纔是模態框真正的位置。
  8. 鼠標按下,我們要得到鼠標在盒子的座標。
  9. 鼠標移動,就讓模態框的座標 設置爲 :鼠標座標 減去盒子座標即可,注意移動事件寫到按下事件裏面。
  10. 鼠標鬆開,就停止拖拽,就是可以讓鼠標移動事件解除

代碼演示:

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            padding: 0px;
            margin: 0px;
        }
        .login-header {
            width: 100%;
            text-align: center;
            height: 30px;
            font-size: 24px;
            line-height: 30px;
        }
        .login {
            display: none;
            width: 512px;
            height: 280px;
            position: fixed;
            border: #ebebeb solid 1px;
            left: 50%;
            top: 50%;
            background: #ffffff;
            box-shadow: 0px 0px 20px #ddd;
            z-index: 9999;
            transform: translate(-50%, -50%);
        }
        .login-title {
            width: 100%;
            margin: 10px 0px 0px 0px;
            text-align: center;
            line-height: 40px;
            height: 40px;
            font-size: 18px;
            position: relative;
            cursor: move;
        }
        .login-input-content {
            margin-top: 20px;
        }
        .login-button {
            width: 50%;
            margin: 30px auto 0px auto;
            line-height: 40px;
            font-size: 14px;
            border: #ebebeb 1px solid;
            text-align: center;
        }
        .login-bg {
            display: none;
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background: rgba(0, 0, 0, .3);
        }
        a {
            text-decoration: none;
            color: #000000;
        }
        .login-button a {
            display: block;
        }
        .login-input input.list-input {
            float: left;
            line-height: 35px;
            height: 35px;
            width: 350px;
            border: #ebebeb 1px solid;
            text-indent: 5px;
        }
        .login-input {
            overflow: hidden;
            margin: 0px 0px 20px 0px;
        }
        .login-input label {
            float: left;
            width: 90px;
            padding-right: 10px;
            text-align: right;
            line-height: 35px;
            height: 35px;
            font-size: 14px;
        }
        .login-title span {
            position: absolute;
            font-size: 12px;
            right: -20px;
            top: -30px;
            background: #ffffff;
            border: #ebebeb solid 1px;
            width: 40px;
            height: 40px;
            border-radius: 20px;
        }
    </style>
</head
<body>
    <div class="login-header"><a id="link" href="javascript:;">點擊,彈出登錄框</a></div>
    <div id="login" class="login">
        <div id="title" class="login-title">登錄會員
            <span><a id="closeBtn" href="javascript:void(0);" class="close-login">關閉</a></span>
        </div>
        <div class="login-input-content">
            <div class="login-input">
                <label>用戶名:</label>
                <input type="text" placeholder="請輸入用戶名" name="info[username]" id="username" class="list-input">
            </div>
            <div class="login-input">
                <label>登錄密碼:</label>
                <input type="password" placeholder="請輸入登錄密碼" name="info[password]" id="password" class="list-input">
            </div>
        </div>
        <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登錄會員</a></div>
    </div>
    <!-- 遮蓋層 -->
    <div id="bg" class="login-bg"></div>
    <script>
        // 1. 獲取元素
        var login = document.querySelector('.login');
        var mask = document.querySelector('.login-bg');
        var link = document.querySelector('#link');
        var closeBtn = document.querySelector('#closeBtn');
        var title = document.querySelector('#title');
        // 2. 點擊彈出層這個鏈接 link  讓mask 和login 顯示出來
        link.addEventListener('click', function() {
                mask.style.display = 'block';
                login.style.display = 'block';
            })
            // 3. 點擊 closeBtn 就隱藏 mask 和 login 
        closeBtn.addEventListener('click', function() {
                mask.style.display = 'none';
                login.style.display = 'none';
            })
            // 4. 開始拖拽
            // (1) 當我們鼠標按下, 就獲得鼠標在盒子內的座標
        title.addEventListener('mousedown', function(e) {
            var x = e.pageX - login.offsetLeft;
            var y = e.pageY - login.offsetTop;
            // (2) 鼠標移動的時候,把鼠標在頁面中的座標,減去 鼠標在盒子內的座標就是模態框的left和top值
            document.addEventListener('mousemove', move)
            function move(e) {
                login.style.left = e.pageX - x + 'px';
                login.style.top = e.pageY - y + 'px';
            }
            // (3) 鼠標彈起,就讓鼠標移動事件移除
            document.addEventListener('mouseup', function() {
                document.removeEventListener('mousemove', move);
            })
        })
    </script>
</body>
</html>

13.1.5 案例講解-仿京東放大鏡

案例效果圖:

[圖片上傳失敗...(image-e6ecc1-1607417619813)]

思路:

  1. 黃色的遮擋層跟隨鼠標功能。
  2. 把鼠標座標給遮擋層不合適。因爲遮擋層座標以父盒子爲準。
  3. 首先是獲得鼠標在盒子的座標。
  4. 之後把數值給遮擋層做爲left 和top值。
  5. 此時用到鼠標移動事件,但是還是在小圖片盒子內移動。
  6. 發現,遮擋層位置不對,需要再減去盒子自身高度和寬度的一半。
  7. 遮擋層不能超出小圖片盒子範圍。
  8. 如果小於零,就把座標設置爲0
  9. 如果大於遮擋層最大的移動距離,就把座標設置爲最大的移動距離
  10. 遮擋層的最大移動距離:小圖片盒子寬度 減去 遮擋層盒子寬度

案例目錄結構:

[圖片上傳失敗...(image-ea6363-1607417619813)]

代碼演示:

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>手機詳情頁!</title>
    <meta name="description" content="品優購JD.COM-專業的綜合網上購物商城,銷售家電、數碼通訊、電腦、家居百貨、服裝服飾、母嬰、圖書、食品等數萬個品牌優質商品.便捷、誠信的服務,爲您提供愉悅的網上購物體驗!" />
    <meta name="Keywords" content="網上購物,網上商城,手機,筆記本,電腦,MP3,CD,VCD,DV,相機,數碼,配件,手錶,存儲卡,品優購" />
    <!-- 引入facicon.ico網頁圖標 -->
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
    <!-- 引入css 初始化的css 文件 -->
    <link rel="stylesheet" href="css/base.css">
    <!-- 引入公共樣式的css 文件 -->
    <link rel="stylesheet" href="css/common.css">
    <!-- 引入詳情頁面的css文件 -->
    <link rel="stylesheet" href="css/detail.css">
    <!-- 引入我們的js 文件 -->
    <script src="js/detail.js"></script>
</head>
<body>
    <!-- 頂部快捷導航start -->
    <div class="shortcut">
        <div class="w">
            <div class="fl">
                <ul>
                    <li>品優購歡迎您! </li>
                    <li>
                        <a href="#">請登錄</a>
                        <a href="#" class="style-red">免費註冊</a>
                    </li>
                </ul>
            </div>
            <div class="fr">
                <ul>
                    <li><a href="#">我的訂單</a></li>
                    <li class="spacer"></li>
                    <li>
                        <a href="#">我的品優購</a>
                        <i class="icomoon"></i>
                    </li>
                    <li class="spacer"></li>
                    <li><a href="#">品優購會員</a></li>
                    <li class="spacer"></li>
                    <li><a href="#">企業採購</a></li>
                    <li class="spacer"></li>
                    <li><a href="#">關注品優購</a> <i class="icomoon"></i></li>
                    <li class="spacer"></li>
                    <li><a href="#">客戶服務</a> <i class="icomoon"></i></li>
                    <li class="spacer"></li>
                    <li><a href="#">網站導航</a> <i class="icomoon"></i></li>
                </ul>
            </div>
        </div>
    </div>
    <!-- 頂部快捷導航end  -->
    <!-- header製作 -->
    <div class="header w">
        <!-- logo -->
        <div class="logo">
            <h1>
                <a href="index.html" title="品優購">品優購</a>
            </h1>
        </div>
        <!-- search -->
        <div class="search">
            <input type="text" class="text" value="請搜索內容...">
            <button class="btn">搜索</button>
        </div>
        <!-- hotwrods -->
        <div class="hotwrods">
            <a href="#" class="style-red">優惠購首發</a>
            <a href="#">億元優惠</a>
            <a href="#">9.9元團購</a>
            <a href="#">美滿99減30</a>
            <a href="#">辦公用品</a>
            <a href="#">電腦</a>
            <a href="#">通信</a>
        </div>
        <div class="shopcar">
            <i class="car"> </i>我的購物車 <i class="arrow">  </i>
            <i class="count">80</i>
        </div>
    </div>
    <!-- header 結束 -->
    <!-- nav start -->
    <div class="nav">
        <div class="w">
            <div class="dropdown fl">
                <div class="dt"> 全部商品分類 </div>
                <div class="dd" style="display: none;">
                    <ul>
                        <li class="menu_item"><a href="#">家用電器</a> <i>  </i> </li>
                        <li class="menu_item">
                            <a href="list.html">手機</a> 、
                            <a href="#">數碼</a> 、
                            <a href="#">通信</a>
                            <i>  </i>
                        </li>
                        <li class="menu_item"><a href="#">電腦、辦公</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">家居、傢俱、家裝、廚具</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">男裝、女裝、童裝、內衣</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">個戶化妝、清潔用品、寵物</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">鞋靴、箱包、珠寶、奢侈品</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">運動戶外、鐘錶</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">汽車、汽車用品</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">母嬰、玩具樂器</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">食品、酒類、生鮮、特產</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">醫藥保健</a> <i>  </i> </li>
                        <li class="menu_item"><a href="#">圖書、音像、電子書</a> <i> </i> </li>
                        <li class="menu_item"><a href="#">彩票、旅行、充值、票務</a> <i> </i> </li>
                        <li class="menu_item"><a href="#">理財、衆籌、白條、保險</a> <i>  </i> </li>
                    </ul>
                </div>
            </div>
            <!-- 右側導航 -->
            <div class="navitems fl">
                <ul>
                    <li><a href="#">服裝城</a></li>
                    <li><a href="#">美妝館</a></li>
                    <li><a href="#">傳智超市</a></li>
                    <li><a href="#">全球購</a></li>
                    <li><a href="#">閃購</a></li>
                    <li><a href="#">團購</a></li>
                    <li><a href="#">拍賣</a></li>
                    <li><a href="#">有趣</a></li>
                </ul>
            </div>
        </div>
    </div>
    <!-- nav end -->
    <!-- 詳情頁內容部分     -->
    <div class="de_container w">
        <!-- 麪包屑導航 -->
        <div class="crumb_wrap">
            <a href="#">手機、數碼、通訊</a> 〉 <a href="#">手機   </a> 〉 <a href="#">Apple蘋果   </a> 〉 <a href="#">iphone 6S Plus系類</a>
        </div>
        <!-- 產品介紹模塊 -->
        <div class="product_intro clearfix">
            <!-- 預覽區域 -->
            <div class="preview_wrap fl">
                <div class="preview_img">
                    <img src="upload/s3.png" alt="">
                    <div class="mask"></div>
                    <div class="big">
                        <img src="upload/big.jpg" alt="" class="bigImg">
                    </div>
                </div>
                <div class="preview_list">
                    <a href="#" class="arrow_prev"></a>
                    <a href="#" class="arrow_next"></a>
                    <ul class="list_item">
                        <li>
                            <img src="upload/pre.jpg" alt="">
                        </li>
                        <li class="current">
                            <img src="upload/pre.jpg" alt="">
                        </li>
                        <li>
                            <img src="upload/pre.jpg" alt="">
                        </li>
                        <li>
                            <img src="upload/pre.jpg" alt="">
                        </li>
                        <li>
                            <img src="upload/pre.jpg" alt="">
                        </li>
                    </ul>
                </div>
            </div>
            <!-- 產品詳細信息 -->
            <div class="itemInfo_wrap fr">
                <div class="sku_name">
                    Apple iPhone 6s(A1700)64G玫瑰金色 移動通信電信4G手機
                </div>
                <div class="news">
                    推薦選擇下方[移動優惠購],手機套餐齊搞定,不用換號,每月還有花費返
                </div>
                <div class="summary">
                    <dl class="summary_price">
                        <dt>價格</dt>
                        <dd>
                            <i class="price">¥5299.00 </i>
                            <a href="#">降價通知</a>
                            <div class="remark">累計評價612188</div>
                        </dd>
                    </dl>
                    <dl class="summary_promotion">
                        <dt>促銷</dt>
                        <dd>
                            <em>加購價</em> 滿999.00另加20.00元,或滿1999.00另加30.00元,或滿2999.00另加40.00元,即可在購物車換 購熱銷商品 詳情 》
                        </dd>
                    </dl>
                    <dl class="summary_support">
                        <dt>支持</dt>
                        <dd>以舊換新,閒置手機回收 4G套餐超值搶 禮品購</dd>
                    </dl>
                    <dl class="choose_color">
                        <dt>選擇顏色</dt>
                        <dd>
                            <a href="javascript:;" class="current">玫瑰金</a>
                            <a href="javascript:;">金色</a>
                            <a href="javascript:;">白色</a>
                            <a href="javascript:;">土豪色</a>
                        </dd>
                    </dl>
                    <dl class="choose_version">
                        <dt>選擇版本</dt>
                        <dd>
                            <a href="javascript:;" class="current">公開版</a>
                            <a href="javascript:;">移動4G</a>
                        </dd>
                    </dl>
                    <dl class="choose_type">
                        <dt>購買方式</dt>
                        <dd>
                            <a href="javascript:;" class="current">官方標配</a>
                            <a href="javascript:;">移動優惠購</a>
                            <a href="javascript:;">電信優惠購</a>
                        </dd>
                    </dl>
                    <div class="choose_btns">
                        <div class="choose_amount">
                            <input type="text" value="1">
                            <a href="javascript:;" class="add">+</a>
                            <a href="javascript:;" class="reduce">-</a>
                        </div>
                        <a href="#" class="addcar">加入購物車</a>
                    </div>
                </div>
            </div>
        </div>
        <!-- 產品細節模塊 product_detail   -->
        <div class="product_detail clearfix">
            <!-- aside -->
            <div class="aside fl">
                <div class="tab_list">
                    <ul>
                        <li class="first_tab ">相關分類</li>
                        <li class="second_tab current">推薦品牌</li>
                    </ul>
                </div>
                <div class="tab_con">
                    <ul>
                        <li>
                            <img src="upload/aside_img.jpg" alt="">
                            <h5>華爲 HUAWEI P20 Pro 全面屏徠卡</h5>
                            <div class="aside_price">¥19</div>
                            <a href="#" class="as_addcar">加入購物車</a>
                        </li>
                        <li>
                            <img src="upload/aside_img.jpg" alt="">
                            <h5>華爲 HUAWEI P20 Pro 全面屏徠卡</h5>
                            <div class="aside_price">¥19</div>
                            <a href="#" class="as_addcar">加入購物車</a>
                        </li>
                        <li>
                            <img src="upload/aside_img.jpg" alt="">
                            <h5>華爲 HUAWEI P20 Pro 全面屏徠卡</h5>
                            <div class="aside_price">¥19</div>
                            <a href="#" class="as_addcar">加入購物車</a>
                        </li>
                        <li>
                            <img src="upload/aside_img.jpg" alt="">
                            <h5>華爲 HUAWEI P20 Pro 全面屏徠卡</h5>
                            <div class="aside_price">¥19</div>
                            <a href="#" class="as_addcar">加入購物車</a>
                        </li>
                        <li>
                            <img src="upload/aside_img.jpg" alt="">
                            <h5>華爲 HUAWEI P20 Pro 全面屏徠卡</h5>
                            <div class="aside_price">¥19</div>
                            <a href="#" class="as_addcar">加入購物車</a>
                        </li>
                        <li>
                            <img src="upload/aside_img.jpg" alt="">
                            <h5>華爲 HUAWEI P20 Pro 全面屏徠卡</h5>
                            <div class="aside_price">¥19</div>
                            <a href="#" class="as_addcar">加入購物車</a>
                        </li>
                    </ul>
                </div>
            </div>
            <!-- detail -->
            <div class="detail fr">
                <div class="detail_tab_list">
                    <ul>
                        <li class="current">商品介紹</li>
                        <li>規格與包裝</li>
                        <li>售後保障</li>
                        <li>商品評價(50000)</li>
                        <li>手機社區</li>
                    </ul>
                </div>
                <div class="detail_tab_con">
                    <div class="item">
                        <ul class="item_info">
                            <li>分辨率:1920*1080(FHD)</li>
                            <li>後置攝像頭:1200萬像素</li>
                            <li>前置攝像頭:500萬像素</li>
                            <li>核 數:其他</li>
                            <li>頻 率:以官網信息爲準</li>
                            <li>品牌: Apple ♥關注</li>
                            <li>商品名稱:APPLEiPhone 6s Plus</li>
                            <li>商品編號:1861098</li>
                            <li>商品毛重:0.51kg</li>
                            <li>商品產地:中國大陸</li>
                            <li>熱點:指紋識別,Apple Pay,金屬機身,拍照神器</li>
                            <li>系統:蘋果(IOS)</li>
                            <li>像素:1000-1600萬</li>
                            <li>機身內存:64GB</li>
                        </ul>
                        <p>
                            <a href="#" class="more">查看更多參數</a>
                        </p>
                        <img src="upload/detail_img1.jpg" alt="">
                        <img src="upload/detail_img2.jpg" alt="">
                        <img src="upload/detail_img3.jpg" alt="">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- 詳情頁內容部分     -->
    <!-- footer start -->
    <div class="footer">
        <div class="w">
            <!-- mod_service -->
            <div class="mod_service">
                <ul>
                    <li>
                        <i class="mod-service-icon mod_service_zheng"></i>
                        <div class="mod_service_tit">
                            <h5>正品保障</h5>
                            <p>正品保障,提供發票</p>
                        </div>
                    </li>
                    <li>
                        <i class="mod-service-icon mod_service_kuai"></i>
                        <div class="mod_service_tit">
                            <h5>正品保障</h5>
                            <p>正品保障,提供發票</p>
                        </div>
                    </li>
                    <li>
                        <i class="mod-service-icon mod_service_bao"></i>
                        <div class="mod_service_tit">
                            <h5>正品保障</h5>
                            <p>正品保障,提供發票</p>
                        </div>
                    </li>
                    <li>
                        <i class="mod-service-icon mod_service_bao"></i>
                        <div class="mod_service_tit">
                            <h5>正品保障</h5>
                            <p>正品保障,提供發票</p>
                        </div>
                    </li>
                    <li>
                        <i class="mod-service-icon mod_service_bao"></i>
                        <div class="mod_service_tit">
                            <h5>正品保障</h5>
                            <p>正品保障,提供發票</p>
                        </div>
                    </li>
                </ul>
            </div>
            <!-- mod_help -->
            <div class="mod_help">
                <dl class="mod_help_item">
                    <dt>購物指南</dt>
                    <dd> <a href="#">購物流程 </a></dd>
                    <dd> <a href="#">會員介紹 </a></dd>
                    <dd> <a href="#">生活旅行/團購 </a></dd>
                    <dd> <a href="#">常見問題 </a></dd>
                    <dd> <a href="#">大家電 </a></dd>
                    <dd> <a href="#">聯繫客服 </a></dd>
                </dl>
                <dl class="mod_help_item">
                    <dt>購物指南</dt>
                    <dd> <a href="#">購物流程 </a></dd>
                    <dd> <a href="#">會員介紹 </a></dd>
                    <dd> <a href="#">生活旅行/團購 </a></dd>
                    <dd> <a href="#">常見問題 </a></dd>
                    <dd> <a href="#">大家電 </a></dd>
                    <dd> <a href="#">聯繫客服 </a></dd>
                </dl>
                <dl class="mod_help_item">
                    <dt>購物指南</dt>
                    <dd> <a href="#">購物流程 </a></dd>
                    <dd> <a href="#">會員介紹 </a></dd>
                    <dd> <a href="#">生活旅行/團購 </a></dd>
                    <dd> <a href="#">常見問題 </a></dd>
                    <dd> <a href="#">大家電 </a></dd>
                    <dd> <a href="#">聯繫客服 </a></dd>
                </dl>
                <dl class="mod_help_item">
                    <dt>購物指南</dt>
                    <dd> <a href="#">購物流程 </a></dd>
                    <dd> <a href="#">會員介紹 </a></dd>
                    <dd> <a href="#">生活旅行/團購 </a></dd>
                    <dd> <a href="#">常見問題 </a></dd>
                    <dd> <a href="#">大家電 </a></dd>
                    <dd> <a href="#">聯繫客服 </a></dd>
                </dl>
                <dl class="mod_help_item">
                    <dt>購物指南</dt>
                    <dd> <a href="#">購物流程 </a></dd>
                    <dd> <a href="#">會員介紹 </a></dd>
                    <dd> <a href="#">生活旅行/團購 </a></dd>
                    <dd> <a href="#">常見問題 </a></dd>
                    <dd> <a href="#">大家電 </a></dd>
                    <dd> <a href="#">聯繫客服 </a></dd>
                </dl>
                <dl class="mod_help_item mod_help_app">
                    <dt>幫助中心</dt>
                    <dd>
                        <img src="upload/erweima.png" alt="">
                        <p>品優購客戶端</p>
                    </dd>
                </dl>
            </div>
            <!-- mod_copyright  -->
            <div class="mod_copyright">
                <p class="mod_copyright_links">
                    關於我們 | 聯繫我們 | 聯繫客服 | 商家入駐 | 營銷中心 | 手機品優購 | 友情鏈接 | 銷售聯盟 | 品優購社區 | 品優購公益 | English Site | Contact U
                </p>
                <p class="mod_copyright_info">
                    地址:北京市昌平區建材城西路金燕龍辦公樓一層 郵編:100096 電話:400-618-4000 傳真:010-82935100 郵箱: zhanghj+itcast.cn <br> 京ICP備08001421號京公網安備110108007702
                </p>
            </div>
        </div>
    </div>
    <!-- footer end -->
</body>
</html>

css:

base.css:

/*清除元素默認的內外邊距  */
* {
    margin: 0;
    padding: 0
}
/*讓所有斜體 不傾斜*/
em,
i {
    font-style: normal;
}
/*去掉列表前面的小點*/
li {
    list-style: none;
}
/*圖片沒有邊框   去掉圖片底側的空白縫隙*/
img {
    border: 0;  /*ie6*/
    vertical-align: middle;
}
/*讓button 按鈕 變成小手*/
button {
    cursor: pointer;
}
/*取消鏈接的下劃線*/
a {
    color: #666;
    text-decoration: none;
}
a:hover {
    color: #e33333;
}
button,
input {
    font-family: 'Microsoft YaHei', 'Heiti SC', tahoma, arial, 'Hiragino Sans GB', \\5B8B\4F53, sans-serif;
    /*取消輪廓線 藍色的*/
    outline: none;
}
body {
    background-color: #fff;
    font: 12px/1.5 'Microsoft YaHei', 'Heiti SC', tahoma, arial, 'Hiragino Sans GB', \\5B8B\4F53, sans-serif;
    color: #666
}
.hide,
.none {
    display: none;
}
/*清除浮動*/
.clearfix:after {
    visibility: hidden;
    clear: both;
    display: block;
    content: ".";
    height: 0
}
.clearfix {
    *zoom: 1
}

common.css:

/*公共樣式*/
.fl {
    float: left;
}
.fr {
    float: right;
}
@font-face {
    font-family: 'icomoon';
    src:  url('../fonts/icomoon.eot?7kkyc2');
    src:  url('../fonts/icomoon.eot?7kkyc2#iefix') format('embedded-opentype'),
    url('../fonts/icomoon.ttf?7kkyc2') format('truetype'),
    url('../fonts/icomoon.woff?7kkyc2') format('woff'),
    url('../fonts/icomoon.svg?7kkyc2#icomoon') format('svg');
  font-weight: normal;
  font-style: normal;
}
.fr .icomoon {
    font-family: 'icomoon';
    font-size: 16px;
    line-height: 26px;
}
/*版心*/
.w {
    width: 1200px;
    margin: 0 auto;
}
.style-red {
    color: #c81623;
}
.spacer {
    width: 1px;
    height: 12px;
    background-color: #666;
    margin: 9px 12px 0;
}
/*頂部快捷導航*/
.shortcut {
    height: 31px;
    background-color: #f1f1f1;
    line-height: 31px;
}
.shortcut li {
    float: left;
}
/*header區域*/
.header {
    position: relative;
    height: 105px;
}
.logo {
    position: absolute;
    top: 25px;
    left: 0;
    width: 175px;
    height: 56px;
}
.logo a {
    display: block;
    /*overflow: hidden;*/
    width: 175px;
    height: 56px;
    background: url(../img/logo.png) no-repeat;
    /*text-indent: -999px;*/
    font-size: 0;
}
.search {
    position: absolute;
    top: 25px;
    left: 348px;
}
.text {
    float: left;
    width: 445px;
    height: 32px;
    border: 2px solid #b1191a;
    padding-left: 10px;
    color: #ccc;
}
.btn {
    float: left;
    width: 82px;
    height: 36px;
    background-color: #b1191a;
    border: 0;
    font-size: 16px;
    color: #fff;
}
.hotwrods {
    position: absolute;
    top: 65px;
    left: 348px;
}
.hotwrods a {
    margin: 0 10px;
}
.shopcar {
    position: absolute;
    top:25px;
    right: 64px;
    width: 138px;
    height: 34px;
    border: 1px solid #dfdfdf;
    background-color: #f7f7f7;
    line-height: 34px;
    text-align: center;
}
.car {
    font-family: 'icomoon';
    color: #da5555;
}
.arrow {
    font-family: 'icomoon';
    margin-left: 5px;
}
.count {
    position: absolute;
    top: -5px;
    /*應該是左側對齊 文字才能往右走顯示*/
    left: 100px;
    background-color: #e60012;
    height: 14px;
    padding: 0 3px;
    line-height: 14px;
    color: #fff;
    /*border-radius: 左上角 右上角  右下角  左下角;*/
    border-radius: 7px 7px 7px 0;
}
/*nav start*/
.nav {
    height: 45px;
    border-bottom: 2px solid #b1191a;
}
.dropdown {
    width: 209px;
    height: 45px;
}
.dropdown .dt {
    height: 100%;
    background-color: #b1191a;
    font-size: 16px;
    color: #fff;
    text-align: center;
    line-height: 45px;
}
.dropdown .dd {
    height: 465px;
    background-color: #c81623;
    margin-top: 2px;
} 
.menu_item:hover {
    background-color: #fff;
}
/*鼠標經過li 裏面的 a變顏色*/
.menu_item:hover a {
    color: #c81623;
}
.menu_item {
    height: 31px;
    line-height: 31px;
    margin-left: 1px;
    padding: 0 10px;
    transition: all .5s;
}
.menu_item:hover {
    padding-left: 20px;
}
.menu_item a {
    font-size: 14px;
    color: #fff;
}
.menu_item i {
    float: right;
    font-family: 'icomoon';
    font-size: 18px;
    color: #fff;
}
.navitems {
    margin-left: 10px;
}
.navitems li {
    float: left;
}
.navitems li a {
    display: block;
    height: 45px;
    padding: 0 25px;
    line-height: 45px;
    font-size: 16px;
}
/*footer 部分*/
.footer {
    height: 386px;
    background-color: #f5f5f5;
    padding-top: 30px;
}
.mod_service {
    height: 79px;
    border-bottom: 1px solid #ccc;
}
.mod_service li {
    float: left;
    width: 240px;
    height: 79px;

}
.mod-service-icon {
    /*浮動的盒子 可以直接給大小的 不需要轉換*/
    float: left;
    width: 50px;
    height: 50px;
    margin-left: 35px;
    background: url(../img/icons.png) no-repeat;
}
.mod_service_zheng {
    background-position: -253px -3px;   
}
.mod_service_tit {
    float: left;
    margin-left: 5px;
}
.mod_service_tit h5 {
    margin: 5px 0;
}
.mod_service_kuai {
    background-position: -255px -54px;
}
.mod_service_bao {
    background-position: -257px -105px;
}
.mod_help {
    height: 187px;
    border-bottom: 1px solid #ccc;
}
.mod_help_item {
    float: left;
    width: 150px;
    padding: 20px 0 0 50px;
}
.mod_help_item dt {
    height: 25px;
    font-size: 16px;
}
.mod_help_item dd {
    height: 22px;
}
.mod_help_app dt,
.mod_help_app p {
    padding-left: 15px;
}
.mod_help_app img {
    margin: 7px 0;
}
.mod_copyright {
    text-align: center;
}
.mod_copyright_links {
    margin: 20px 0 15px 0;
}
.mod_copyright_info {
    line-height: 18px;
}

detail.css:

/*詳情頁的樣式文件*/
.de_container {
    margin-top: 20px;
}
.crumb_wrap {
    height: 25px;
}
.crumb_wrap a {
    margin-right: 10px;
}
.preview_wrap {
    width: 400px;
    height: 590px;
}
.preview_img {
    position: relative;
    height: 398px;
    border: 1px solid #ccc;
}
.mask {
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 300px;
    height: 300px;
    background: #FEDE4F;
    opacity: .5;
    border: 1px solid #ccc;
    cursor: move;
}
.big {
    display: none;
    position: absolute;
    left: 410px;
    top: 0;
    width: 500px;
    height: 500px;
    background-color: pink;
    z-index: 999;
    border: 1px solid #ccc;
    overflow: hidden;
}
.big img {
    position: absolute;
    top: 0;
    left: 0;
}
.preview_list {
    position: relative;
    height: 60px;
    margin-top: 60px;
}
.list_item {
    width: 320px;
    height: 60px;
    margin: 0 auto;
}
.list_item li {
    float: left;
    width: 56px;
    height: 56px;
    border: 2px solid transparent;
    margin: 0 2px;
}
.list_item li.current {
    border-color: #c81623;
}
.arrow_prev,
.arrow_next {
    position: absolute;
    top: 15px;
    width: 22px;
    height: 32px;
    background-color: purple;
}
.arrow_prev {
    left: 0;
    background: url(../img/arrow-prev.png) no-repeat;
}
.arrow_next {
    right: 0;
    background: url(../img/arrow-next.png) no-repeat;
}
.itemInfo_wrap {
    width: 718px;
}
.sku_name {
    height: 30px;
    font-size: 16px;
    font-weight: 700;
}
.news {
    height: 32px;
    color: #e12228;
}
.summary dl {
    overflow: hidden;
}
.summary dt,
.summary dd {
    float: left;
}
.summary dt {
    width: 60px;
    padding-left: 10px;
    line-height: 36px;
}
.summary_price,
.summary_promotion {
    position: relative;
    padding: 10px 0;
    background-color: #fee9eb;
}
.price {
    font-size: 24px;
    color: #e12228;
}
.summary_price a {
    color: #c81623;
}
.remark {
    position: absolute;
    right: 10px;
    top: 20px;
}
.summary_promotion {
    padding-top: 0;
}
.summary_promotion dd {
    width: 450px;
    line-height: 36px;
}
.summary_promotion em {
    display: inline-block;
    width: 40px;
    height: 22px;
    background-color: #c81623;
    text-align: center;
    line-height: 22px;
    color: #fff;
}
.summary_support dd {
    line-height: 36px;
}
.choose_color a {
    display: inline-block;
    width: 80px;
    height: 41px;
    background-color: #f7f7f7;
    border: 1px solid #ededed;
    text-align: center;
    line-height: 41px;
}
.summary a.current {
    border-color: #c81623;
}
.choose_version {
    margin: 10px 0;
}
.choose_version a,
.choose_type a {
    display: inline-block;
    height: 32px;
    padding: 0 12px;
    background-color: #f7f7f7;
    border: 1px solid #ededed;
    text-align: center;
    line-height: 32px;
}
.choose_btns {
    margin-top: 20px;
}
.choose_amount {
    position: relative;
    float: left;
    width: 50px;
    height: 46px;
    background-color: pink;
}
.choose_amount input {
    width: 33px;
    height: 44px;
    border: 1px solid #ccc;
    text-align: center;
}
.add,
.reduce {
    position: absolute;
    right: 0;
    width: 15px;
    height: 22px;
    border: 1px solid #ccc;
    background-color: #f1f1f1;
    text-align: center;
    line-height: 22px;
}
.add {
    top: 0;
}
.reduce {
    bottom: 0;
    /*禁止鼠標樣式*/
    cursor: not-allowed;
    /* pointer  小手  move  移動  */
}
.addcar {
    float: left;
    width: 142px;
    height: 46px;
    background-color: #c81623;
    text-align: center;
    line-height: 46px;
    font-size: 18px;
    color: #fff;
    margin-left: 10px;
    font-weight: 700;
}
.product_detail {
    margin-bottom: 50px;
}
.aside {
    width: 208px;
    border: 1px solid #ccc;
}
.tab_list {
    overflow: hidden;
    height: 34px;
}
/*把背景顏色 底邊框都給 li*/
.tab_list li {
    float: left;
    background-color: #f1f1f1;
    border-bottom: 1px solid #ccc;
    height: 33px;
    text-align: center;
    line-height: 33px;
}
/*鼠標單擊 li 變化樣式   背景變白色 去掉下邊框 文字變顏色*/
.tab_list .current {
    background-color: #fff;
    border-bottom: 0;
    color: red;
}
.first_tab {
    width: 104px;
}
.second_tab {
    width: 103px;
    border-left: 1px solid #ccc;
}
.tab_con {
    padding: 0 10px;
}
.tab_con li {
    border-bottom: 1px solid #ccc;
}
.tab_con li h5 {
    /*超出的文字省略號顯示*/
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 400;
}
.aside_price {
    font-weight: 700;
    margin: 10px 0;
}
.as_addcar {
    display: block;
    width: 88px;
    height: 26px;
    border: 1px solid #ccc;
    background-color: #f7f7f7;
    margin: 10px auto;
    text-align: center;
    line-height: 26px;
}
.detail {
    width: 978px;
}
.detail_tab_list {
    height: 39px;
    border: 1px solid #ccc;
    background-color: #f1f1f1;
}
.detail_tab_list li {
    float: left;
    height: 39px;
    line-height: 39px;
    padding: 0 20px;
    text-align: center;
    cursor: pointer;
}
.detail_tab_list .current {
    background-color: #c81623;
    color: #fff;
}
.item_info {
    padding: 20px 0 0 20px;
}
.item_info li {
    line-height: 22px;
}
.more {
    float: right;
    font-weight: 700;
    font-family: 'icomoon';
}

js:

/* detail.js */
window.addEventListener('load', function() {
    var preview_img = document.querySelector('.preview_img');
    var mask = document.querySelector('.mask');
    var big = document.querySelector('.big');
    // 1. 當我們鼠標經過 preview_img 就顯示和隱藏 mask 遮擋層 和 big 大盒子
    preview_img.addEventListener('mouseover', function() {
        mask.style.display = 'block';
        big.style.display = 'block';
    })
    preview_img.addEventListener('mouseout', function() {
            mask.style.display = 'none';
            big.style.display = 'none';
        })
        // 2. 鼠標移動的時候,讓黃色的盒子跟着鼠標來走
    preview_img.addEventListener('mousemove', function(e) {
        // (1). 先計算出鼠標在盒子內的座標
        var x = e.pageX - this.offsetLeft;
        var y = e.pageY - this.offsetTop;
        // console.log(x, y);
        // (2) 減去盒子高度 300的一半 是 150 就是我們mask 的最終 left 和top值了
        // (3) 我們mask 移動的距離
        var maskX = x - mask.offsetWidth / 2;
        var maskY = y - mask.offsetHeight / 2;
        // (4) 如果x 座標小於了0 就讓他停在0 的位置
        // 遮擋層的最大移動距離
        var maskMax = preview_img.offsetWidth - mask.offsetWidth;
        if (maskX <= 0) {
            maskX = 0;
        } else if (maskX >= maskMax) {
            maskX = maskMax;
        }
        if (maskY <= 0) {
            maskY = 0;
        } else if (maskY >= maskMax) {
            maskY = maskMax;
        }
        mask.style.left = maskX + 'px';
        mask.style.top = maskY + 'px';
        // 3. 大圖片的移動距離 = 遮擋層移動距離 * 大圖片最大移動距離 / 遮擋層的最大移動距離
        // 大圖
        var bigIMg = document.querySelector('.bigImg');
        // 大圖片最大移動距離
        var bigMax = bigIMg.offsetWidth - big.offsetWidth;
        // 大圖片的移動距離 X Y
        var bigX = maskX * bigMax / maskMax;
        var bigY = maskY * bigMax / maskMax;
        bigIMg.style.left = -bigX + 'px';
        bigIMg.style.top = -bigY + 'px';

    })
})

13.2 元素可視區client系列

client 翻譯過來就是客戶端,我們使用 client 系列的相關屬性來獲取元素可視區的相關信息。通過 client
系列的相關屬性可以動態的得到該元素的邊框大小、元素大小等

[圖片上傳失敗...(image-6a4fb0-1607417619813)]

​ [圖片上傳失敗...(image-76c457-1607417619813)]

13.2.1 clientTop

語法:

element.clientTop

作用:

返回元素上邊框的大小

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        // client 寬度 和我們offsetWidth 最大的區別就是 不包含邊框
        var div = document.querySelector('div');
        console.log(div.clientTop)
    </script>
</body>
</html>

13.2.2 clientLeft

語法:

element.clientLeft

作用:

返回元素左邊框的大小

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        // client 寬度 和我們offsetWidth 最大的區別就是 不包含邊框
        var div = document.querySelector('div');
        console.log(div.clientLeft)
    </script>
</body>
</html>

13.2.3 clientWidth

語法:

element.clientWidth

作用:

返回元素自身包括padding、內容區的寬度,不含邊框,返回數值不帶單位

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        // client 寬度 和我們offsetWidth 最大的區別就是 不包含邊框
        var div = document.querySelector('div');
        console.log(div.clientTop)
    </script>
</body>
</html>

13.2.4 clientHeight

語法:

element.clientHeight

作用:

返回元素自身包括padding、內容區的高度,不含邊框,返回數值不帶單位

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        // client 寬度 和我們offsetWidth 最大的區別就是 不包含邊框
        var div = document.querySelector('div');
        console.log(div.clientHeight)
    </script>
</body>
</html>

13.3 立即執行函數

13.3.1 立即執行函數

立即執行函數 (function(){})() 或者 (function(){}())

主要作用:

創建一個獨立的作用域。 避免了命名衝突問題

代碼演示:

<script>
// 1.立即執行函數: 不需要調用,立馬能夠自己執行的函數
function fn() {
    console.log(1);
}
fn();
// 2. 寫法 也可以傳遞參數進來
// 1.(function() {})()    或者  2. (function(){}());
(function(a, b) {
    console.log(a + b);
    var num = 10;
})(1, 2); // 第二個小括號可以看做是調用函數
(function sum(a, b) {
    console.log(a + b);
    var num = 10; // 局部變量
}(2, 3));
// 3. 立即執行函數最大的作用就是 獨立創建了一個作用域, 裏面所有的變量都是局部變量 不會有命名衝突的情況
</script>

13.3.2 淘寶 flexible.js 源碼分析

(function flexible(window, document) {
    // 獲取的html 的根元素
    var docEl = document.documentElement
        // dpr 物理像素比
    var dpr = window.devicePixelRatio || 1
    // adjust body font size  設置我們body 的字體大小
    function setBodyFontSize() {
        // 如果頁面中有body 這個元素 就設置body的字體大小
        if (document.body) {
            document.body.style.fontSize = (12 * dpr) + 'px'
        } else {
            // 如果頁面中沒有body 這個元素,則等着 我們頁面主要的DOM元素加載完畢再去設置body
            // 的字體大小
            document.addEventListener('DOMContentLoaded', setBodyFontSize)
        }
    }
    setBodyFontSize();
    // set 1rem = viewWidth / 10    設置我們html 元素的文字大小
    function setRemUnit() {
        var rem = docEl.clientWidth / 10
        docEl.style.fontSize = rem + 'px'
    }
    setRemUnit()
    // reset rem unit on page resize  當我們頁面尺寸大小發生變化的時候,要重新設置下rem 的大小
    window.addEventListener('resize', setRemUnit)
        // pageshow 是我們重新加載頁面觸發的事件
    window.addEventListener('pageshow', function(e) {
        // e.persisted 返回的是true 就是說如果這個頁面是從緩存取過來的頁面,也需要從新計算一下rem 的大小
        if (e.persisted) {
            setRemUnit()
        }
    })
    // detect 0.5px supports  有些移動端的瀏覽器不支持0.5像素的寫法
    if (dpr >= 2) {
        var fakeBody = document.createElement('body')
        var testElement = document.createElement('div')
        testElement.style.border = '.5px solid transparent'
        fakeBody.appendChild(testElement)
        docEl.appendChild(fakeBody)
        if (testElement.offsetHeight === 1) {
            docEl.classList.add('hairlines')
        }
        docEl.removeChild(fakeBody)
    }
}(window, document))

13.3.3 淘寶flexibleJS源碼分析之pageshow事件

下面三種情況都會刷新頁面都會觸發 load 事件

  1. a標籤的超鏈接
  2. F5或者刷新按鈕(強制刷新)
  3. 前進後退按鈕

但是 火狐中,有個特點,有個“往返緩存”,這個緩存中不僅保存着頁面數據,還保存了DOM和JavaScript的狀態;實際上是將整個頁面都保存在了內存裏。

所以此時後退按鈕不能刷新頁面。

此時可以使用 pageshow事件來觸發。,這個事件在頁面顯示時觸發,無論頁面是否來自緩存。在重新加載頁面中,pageshow會在load事件觸發後觸發;根據事件對象中的persisted來判斷是否是緩存中的頁面觸發的pageshow事件

注意:這個事件給window添加

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        // console.log(window.devicePixelRatio);
        window.addEventListener('pageshow', function() {
            alert(11);
        })
    </script>
    <a href="http://www.usian.cn">鏈接</a>
</body>
</html>

13.4 元素滾動scroll系列

13.4.1 scroll 概述

scroll 翻譯過來就是滾動的,我們使用 scroll 系列的相關屬性可以動態的得到該元素的大小、滾動距離等。

[圖片上傳失敗...(image-65884d-1607417619813)]

​ [圖片上傳失敗...(image-5de20c-1607417619813)]

頁面被捲去的頭部:

如果瀏覽器的高(或寬)度不足以顯示整個頁面時,會自動出現滾動條。當滾動條向下滾動時,頁面上面被隱藏掉的高度,我們就稱爲頁面被捲去的頭部。滾動條在滾動時會觸發 onscroll事件。

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
            overflow: auto;
        }
    </style>
</head>
<body>
    <div>
        我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容
    </div>
    <script>
        // scroll 系列
        var div = document.querySelector('div');
        console.log(div.scrollHeight);
        console.log(div.clientHeight);
        // scroll滾動事件當我們滾動條發生變化會觸發的事件
        div.addEventListener('scroll', function() {
            console.log(div.scrollTop);
        })
    </script>
</body>
</html>

13.4.2 案例講解-仿淘寶固定右側側邊欄

  1. 原先側邊欄是絕對定位
  2. 當頁面滾動到一定位置,側邊欄改爲固定定位
  3. 頁面繼續滾動,會讓 返回頂部顯示出來

案例效果圖:

[圖片上傳失敗...(image-a8a6dd-1607417619813)]

思路:

1. 需要用到頁面滾動事件 scroll  因爲是頁面滾動,所以事件源是document
2. 滾動到某個位置,就是判斷頁面被捲去的上部值。
3. 頁面被捲去的頭部:可以通過window.pageYOffset 獲得  如果是被捲去的左側window.pageXOffset
4. 注意,元素被捲去的頭部是element.scrollTop  , 如果是頁面被捲去的頭部 則是 window.pageYOffset
5. 其實這個值 可以通過盒子的 offsetTop可以得到,如果大於等於這個值,就可以讓盒子固定定位了

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .slider-bar {
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }
        .w {
            width: 1200px;
            margin: 10px auto;
        }
        .header {
            height: 150px;
            background-color: purple;
        }
        .banner {
            height: 250px;
            background-color: skyblue;
        }
        .main {
            height: 1000px;
            background-color: yellowgreen;
        }
        span {
            display: none;
            position: absolute;
            bottom: 0;
        }
    </style>
</head>
<body>
    <div class="slider-bar">
        <span class="goBack">返回頂部</span>
    </div>
    <div class="header w">頭部區域</div>
    <div class="banner w">banner區域</div>
    <div class="main w">主體部分</div>
    <script>
        //1. 獲取元素
        var sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        // banner.offestTop 就是被捲去頭部的大小 一定要寫到滾動的外面
        var bannerTop = banner.offsetTop
            // 當我們側邊欄固定定位之後應該變化的數值
        var sliderbarTop = sliderbar.offsetTop - bannerTop;
        // 獲取main 主體元素
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');
        var mainTop = main.offsetTop;
        // 2. 頁面滾動事件 scroll
        document.addEventListener('scroll', function() {
            // console.log(11);
            // window.pageYOffset 頁面被捲去的頭部
            // console.log(window.pageYOffset);
            // 3 .當我們頁面被捲去的頭部大於等於了 172 此時 側邊欄就要改爲固定定位
            if (window.pageYOffset >= bannerTop) {
                sliderbar.style.position = 'fixed';
                sliderbar.style.top = sliderbarTop + 'px';
            } else {
                sliderbar.style.position = 'absolute';
                sliderbar.style.top = '300px';
            }
            // 4. 當我們頁面滾動到main盒子,就顯示 goback模塊
            if (window.pageYOffset >= mainTop) {
                goBack.style.display = 'block';
            } else {
                goBack.style.display = 'none';
            }
        })
    </script>
</body>
</html>

頁面被捲去的頭部兼容性解決方案

需要注意的是,頁面被捲去的頭部,有兼容性問題,因此被捲去的頭部通常有如下幾種寫法:

  1. 聲明瞭 DTD,使用 document.documentElement.scrollTop
  2. 未聲明 DTD,使用 document.body.scrollTop
  3. 新方法 window.pageYOffset和 window.pageXOffset,IE9 開始支持
function getScroll() {
    return {
      left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
      top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
    };
 } 
getScroll().left

13.5 mouseenter和mouseover的區別

13.5.1 mouseenter

  • 當鼠標移動到元素上時就會觸發mouseenter 事件,mouseenter 只會經過自身盒子觸發
  • mouseenter不會冒泡
  • 跟mouseenter搭配鼠標離開 mouseleave 同樣不會冒泡

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .father {
            width: 300px;
            height: 300px;
            background-color: pink;
            margin: 100px auto;
        }
        .son {
            width: 200px;
            height: 200px;
            background-color: purple;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <script>
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        father.addEventListener('mouseenter', function() {
            console.log(11);
        })
    </script>
</body>
</html>

13.5.2 mouseover

  • mouseover 鼠標經過自身盒子會觸發,經過子盒子還會觸發
  • mouseover會冒泡

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .father {
            width: 300px;
            height: 300px;
            background-color: pink;
            margin: 100px auto;
        }
        .son {
            width: 200px;
            height: 200px;
            background-color: purple;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <script>
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        father.addEventListener('mouseover', function() {
            console.log(11);
        })
    </script>
</body>
</html>

13.6 動畫封裝函數

13.6.1 動畫實現原理

核心原理:通過定時器 setInterval() 不斷移動盒子位置。

實現步驟:

  1. 獲得盒子當前位置
  2. 讓盒子在當前位置加上1個移動距離
  3. 利用定時器不斷重複這個操作
  4. 加一個結束定時器的條件
  5. 注意此元素需要添加定位,才能使用element.style.left

代碼演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        // 動畫原理
        // 1. 獲得盒子當前位置  
        // 2. 讓盒子在當前位置加上1個移動距離
        // 3. 利用定時器不斷重複這個操作
        // 4. 加一個結束定時器的條件
        // 5. 注意此元素需要添加定位, 才能使用element.style.left
        var div = document.querySelector('div');
        var timer = setInterval(function() {
            if (div.offsetLeft >= 400) {
                // 停止動畫 本質是停止定時器
                clearInterval(timer);
            }
            div.style.left = div.offsetLeft + 1 + 'px';
        }, 30);
    </script>
</body>
</html>

效果:

[圖片上傳失敗...(image-8d28e2-1607417619813)]

13.6.2 簡單動畫函數封裝

原理:利用定時器不斷的移動元素的位置,即改變它的left值;當移動的left值大於等於目標位置時清空定時器

代碼演示:

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        span {
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: purple;
        }
    </style>
</head>
<body>
    <div></div>
    <span>夏雨荷</span>
    <script src="./move.js"></script>
    <script>
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        // 調用函數
        animate(div, 300);
        animate(span, 200);
    </script>
</body>
</html>

js:

/* move.js */
// 簡單動畫函數封裝obj目標對象 target 目標位置
function animate(obj, target) {
    var timer = setInterval(function() {
        if (obj.offsetLeft >= target) {
            // 停止動畫 本質是停止定時器
            clearInterval(timer);
        }
        obj.style.left = obj.offsetLeft + 1 + 'px';
    }, 30);
}

效果:

[圖片上傳失敗...(image-f39375-1607417619813)]

13.6.3 動畫函數-給不同元素記錄不同定時器

如果多個元素都使用這個動畫函數,每次都要var 聲明定時器。我們可以給不同的元素使用不同的定時器(自己專門用自己的定時器)。

核心原理:利用 JS 是一門動態語言,可以很方便的給當前對象添加屬性。

代碼演示:

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        span {
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: purple;
        }
    </style>
</head>
<body>
    <button>點擊夏雨荷才走</button>
    <div></div>
    <span>夏雨荷</span>
    <script src="./move.js"></script>
    <script>
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        var btn = document.querySelector('button');
        // 調用函數
        animate(div, 300);
        btn.addEventListener('click', function() {
            animate(span, 200);
        })
    </script>
</body>
</html>

js:

/* move.js */
// var obj = {};
// obj.name = 'andy';
// 簡單動畫函數封裝obj目標對象 target 目標位置
// 給不同的元素指定了不同的定時器
function animate(obj, target) {
    // 當我們不斷的點擊按鈕,這個元素的速度會越來越快,因爲開啓了太多的定時器
    // 解決方案就是 讓我們元素只有一個定時器執行
    // 先清除以前的定時器,只保留當前的一個定時器執行
    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
        if (obj.offsetLeft >= target) {
            // 停止動畫 本質是停止定時器
            clearInterval(obj.timer);
        }
        obj.style.left = obj.offsetLeft + 1 + 'px';
    }, 30);
}

效果:

[圖片上傳失敗...(image-2e6e58-1607417619813)]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章