天天看點

元素偏移量 offset 系列

文章目錄

  • ​​offset 概述​​
  • ​​offset 與 style 差別​​
  • ​​案例一:模态框拖拽​​
  • ​​思路:​​
  • ​​代碼實作:​​
  • ​​案例二:京東放大鏡​​
  • ​​思路:(分為三大部分)​​
  • ​​代碼實作​​

offset 概述

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

  • 獲得元素距離帶有定位父元素的位置
  • 獲得元素自身的大小(寬度高度)
  • 傳回的數值都不帶機關
元素偏移量 offset 系列

offset 系列常用屬性:

元素偏移量 offset 系列
<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>      

offset 與 style 差別

​offset​

  • offset 可以得到任意樣式表中的樣式值
  • offset 系列獲得的數值是沒有機關的
  • offsetWidth 包含padding+border+width
  • offsetWidth 等屬性是隻讀屬性,隻能擷取不能指派
  • 是以,我們想要擷取元素大小位置,用offset更合适

​sytle​

  • style 隻能得到行内樣式表中的樣式值
  • style.width 獲得的是帶有機關的字元串
  • style.width 獲得不包含padding和border 的值
  • style.width 是可讀寫屬性,可以擷取也可以指派
  • 是以,我們想要給元素更改值,則需要用style改變

案例一:模态框拖拽

其本質就是實作一個拖動效果

思路:

① 滑鼠按下,我們要得到滑鼠在盒子的坐标。

② 滑鼠移動,就讓模态框的坐标 設定為 : 滑鼠坐标 減去盒子坐标即可,注意移動事件寫到按下事件裡面。

③ 滑鼠松開,就停止拖拽,就是可以讓滑鼠移動事件解除

代碼實作:

<style>div {
            height: 200px;
            width: 200px;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%,-50%);
            background-color: orange;
            cursor: move;
        }</style>
</head>
<body>
    <div> </div>
    <script>let box = document.getElementsByTagName('div')[0];
        box.onmousedown = function(e){
            console.log(e);
            let abx = e.pageX - box.offsetLeft;
            let aby = e.pageY - box.offsetTop;
            box.onmousemove = function(e){
                console.log(1);
                box.style.top = (e.pageY - aby) + 'px';
                box.style.left = (e.pageX - abx) + 'px';
                box.onmouseup = function(){
                    box.onmousemove = null;

                };
            };
        };</script>
</body>      
注意onmousedown在一直按下滑鼠的時候,不會反複觸發

案例二:京東放大鏡

思路:(分為三大部分)

第一部分:

滑鼠經過小圖檔盒子, 黃色的遮擋層 和 大圖檔盒子顯示,離開隐藏2個盒子功能

做法:

① 滑鼠經過小圖檔盒子, 黃色的遮擋層 和 大圖檔盒子顯示,離開隐藏2個盒子功能

② 就是顯示與隐藏

第二部分:

黃色的遮擋層跟随滑鼠功能。

做法:

① 黃色的遮擋層跟随滑鼠功能。

② 把滑鼠坐标給遮擋層不合适。因為遮擋層坐标以父盒子為準。

③ 首先是獲得滑鼠在盒子的坐标。

④ 之後把數值給遮擋層做為left 和top值。

⑤ 此時用到滑鼠移動事件,但是還是在小圖檔盒子内移動。

⑥ 發現,遮擋層位置不對,需要再減去盒子自身高度和寬度的一半。

⑦ 遮擋層不能超出小圖檔盒子範圍。

⑧ 如果小于零,就把坐标設定為0

⑨ 如果大于遮擋層最大的移動距離,就把坐标設定為最大的移動距離

⑩ 遮擋層的最大移動距離: 小圖檔盒子寬度 減去 遮擋層盒子寬度

第三部分:

移動黃色遮擋層,大圖檔跟随移動功能

做法:

元素偏移量 offset 系列

代碼實作

<style>* {
            margin: 0;
            padding: 0;
        }
        div {
            float: left;
            margin-right: 50px;
            /* background-color: orange; */
        }
        .product {
            height: 400px;
            width: 400px;
            position: relative;
            margin-left: 200px;
            border: 1px solid gray;
        }
        .big {
            height: 650px;
            width: 500px;
            overflow: hidden;
            display: none;
            border: 1px solid gray;
            position: relative;
        }
        .watch {
            position: absolute;
            background-color: orange;
            z-index: 5px;
            height: 200px;
            width: 200px;
            opacity: 0.5;
            display: none;
            cursor: move;
        }
        .bigpic {
            display: block;
            position: absolute;
        }</style>
</head>
<body>
    <div class="product">
        <div class="watch"></div>
        <img src="pics\s3.png" alt="">
    </div>
    <div class="big">
        <img src="pics\big.jpg" alt="" class="bigpic">
    </div>
    <script>let product = document.getElementsByClassName('product')[0];
        let watch = document.getElementsByClassName('watch')[0];
        let big = document.getElementsByClassName('big')[0];
        let pic = document.getElementsByTagName('img')[1];
        product.onmouseover = function(e){
            watch.style.display = 'block';
            big.style.display = 'block';
            product.onmouseout = function(){
                watch.style.display = 'none';
                big.style.display = 'none';
            };
        };
        product.onmousemove = function(e){
            markY = e.pageY - product.offsetTop - watch.offsetHeight / 2 ;
            markX = e.pageX - product.offsetLeft - watch.offsetWidth / 2 ;
            if(markX <= 200 && markX >= 0) {watch.style.left = e.pageX - product.offsetLeft - watch.offsetWidth / 2 + 'px';
            pic.style.left = -2 * markX + 'px';}
            else if(markX < 0) watch.style.left = 0 + 'px';
            else watch.style.left = 200 + 'px';
            
            if(markY <= 200 && markY >= 0)  {watch.style.top = e.pageY - product.offsetTop - watch.offsetHeight / 2 + 'px';
             pic.style.top = -2 * markY + 'px';}
            else if(markY < 0) watch.style.top = 0 + 'px';
            else watch.style.top = 200 + 'px';
        };</script>
    
</body>      
注意:
①img是行内元素,不能直接使用定位
②rgba和opacity的差別:
rgba()和opacity都能實作透明效果,但最大的不同是opacity作用于元素,以及元素内的所有内容的透明度,而rgba()隻作用于元素的顔色或其背景色。(設定rgba透明的元素的子元素不會繼承透明效果!)比如,我們寫透明的黑色部分都是用opcity(0.5),但這帶出來一個問題就是如果你在這一div上寫字的話,然後那個字型也會變成透明色。是以我們采取rgba的樣式寫,前面三個數字分别對應r,g,b,的三種顔色,第四位的數字對應的是透明的系數。同時opacity會繼承父元素的 opacity 屬性,而RGBA設定的元素的後代元素不會繼承不透明屬性。

繼續閱讀