第六節盒子模型和盒子模型偏移量

------------------------------------盒子模型常用的八個屬性---------------------------------
Js盒子模型
Js盒子模型指的是通過js提供的一系列的屬性和方法,獲取頁面中元素的樣式信息值

 client系列(當前元素的私有屬性)
 clientWidth/clientHeight:內容的寬度/高度+左右/上下填充,(和內容溢出沒有關系)
 clientLeft:左邊框的寬度(borderLeftWidth)   
 clientTop:上邊框的高度(borderTopWidth)
 //真實的內容寬度和高度其實不是這樣的,真實的高度是要把溢出的高度也要加進來

 offset系列
 offsetHeight/offsetWidth:clientWidth/clientHeight+左右邊框/上下邊框(和內容溢出沒有關系)
 offsetParent:當前元素的參照物
 offsetLeft/offsetTop:當前元素的外邊框距離父級參照物的偏移量

 scroll系列
  1、內容有溢出
  scrollWidth/scrollHeight 內容沒有溢出的情況下和clientWidth/clientHeight一模一樣
  2、內容沒有溢出:
  如果容器中內容有溢出我們獲取的內容以下規則:
  scrollWidth:真實內容的寬度(包含溢出)+左填充
  scrollHeight:真實內容的高度(包含溢出)+上填充
  獲取到的結果都是‘約’等于的值,不同的瀏覽器結果也是不同的,設置overflow: hidden;有影響,在不同的瀏覽器中我們獲取到的結果是不相同的
   scrollLeft/scrollTop滾動條卷去的寬度/高度

   關于瀏覽器本身盒子模型信息
    clientWidth/clientHeight當前瀏覽器可視窗口的高度和寬度(一屏)
    scrollWidth/scrollHeight當前頁面真實的寬度和高度(所有屏的寬度和高度,是一個約等于的值)
 
    不管是哪些屬性,也不管是什么瀏覽器,不管是設置還是獲取,想要兼容都寫兩套
    獲取
    document.documentElement[attr]||document.body[attr]
    設置
    document.documentElement.scrollTop=0;
    document.body.scrollTop=0;

編寫一個有關于操作瀏覽器盒子模型的方法
如果只傳遞了attr沒有傳遞value,默認的意思是獲取樣式值
如果兩個參數都傳遞了,意思是設置某一個樣式屬性值



設置、獲取瀏覽器的寬度和高度
    function win(attr,value){
        if(typeof  value=='undefined'){
              return document.documentElement[attr]||document.body[attr];
        }
        document.documentElement[attr]=value;
        document.body[attr]=value;
}
獲取可視寬:win(“clientHeight”)
設置值:win(“scrollTop,0”)

----------------獲取元素的具體樣式信息值以及Js兼容檢測三種方式--------------

以上獲取的都是組合樣式值,如果想獲取某一個具體的屬性值兩種方式:
1、元素.style.屬性名(需要我們把所有的樣式寫在行內樣式才可以)(真實項目中不常用)(無法實現css和html的分離)
2、使用window.getComputedStyle這個方法獲取所有經過瀏覽器計算過的樣式(只要當前的元素標簽可以在頁面中呈現出來,那么它所有的樣式都是經過瀏覽器計算過的,哪怕樣式沒有寫也可以獲取到)
window.getComputedStyle  ----->function getComputedStyle()
window.getComputedStyle(當前要操作的元素對象,當前元素的偽類一般寫null)
獲取的結果是是經過瀏覽器計算過,是CSSStyleDeclaration這個類的實例,這個實例包含了當前元素的所有樣式屬性值

Js兼容檢測三種方式 1、try catch  使用try catch處理兼容,消耗性能,不得已的情況下使用不是最優的方式
    function getcss(obj, attr) {
        var val = null;
        try {
            val = window.getComputedStyle(obj)[attr];
        } catch (e) {
            val = obj.currentStyle[attr];
        }
        return val;
    }
2、判斷瀏覽器中是否存在這個屬性或方法,存在就兼容,不存在就不兼容  (最優)
     function getcss(obj,attr){
         var val=null;
         if("getComputedStyle" in  window){//判斷某一個屬性是否屬于這個對象
             val=window.getComputedStyle(obj)[attr];
         }else{
             val=obj.currentStyle[attr];
         }
         return val;
     }

3、根據瀏覽器的版本來處理兼容
          function getcss(obj,attr){
             var val=null;
             //判斷某一個屬性是否屬于這個對象
             if(!/MSIE(6|7|8)/.test(window.navigator.userAgent)){
                 val=window.getComputedStyle(obj)[attr];
             }else{
                 val=obj.currentStyle[attr];
             }
             return val;
         }

升級getcss(),部分去掉樣式的單位
  function getcss(obj,attr){
        var val=null;
        var reg=null;
        if("getComputedStyle" in  window){
             val=window.getComputedStyle(obj,null)[attr];
        }else{
            val=obj.currentStyle[attr];
        }
        reg=/^(-?\d+(\.\d+)?)(px|rem|em)$/i;
        return reg.test(val)?parseFloat(val):val;
}
標準瀏覽器和IE瀏覽器獲取的結果是不一樣的----->對于部分樣式屬性,不同瀏覽器獲取的結果不一樣,主要是由于getComputedStyle和currentStyle在某些方面不一樣
獲取復合型值的時候,比如border等需要拆開了來獲取,會避免獲取不到的問題

---------------------------瀏覽器滾動條卷去的高度scrolltop------------------------

1、只讀的屬性
client系列offset系列scrollWidth/scrollHeight都是只讀的屬性

2、可以設置值的屬性
box.scrollTop=0直接回到了容器的頂部

我們的scrollTop的值是存在邊界值的(最大值和最小的值的),最小是0,
最大是box.scrollHeight-box.clientHeight




------------------------------------------------獲取元素的偏移量-----------------------------------------------------
盒子模型案例分析offsetParent和offsetLeft/offsetTop 的特點
parentNode:父節點
    var outer=document.getElementById('outer');
    var inner=document.getElementById('inner');
    var center=document.getElementById('center');
//    console.log(center.parentNode);
//    console.log(document.body.parentNode);
//    console.log(document.documentElement.parentNode);
//    console.log(document.parentNode);
//    console.log(document.aa);

Null和undefined都代表沒有,但是null是值不存在,undefined是連這個屬性都不存在

offsetParent:父級參照物,在同一個平面中,最外層的元素是里面所有的父級參照物(和HTML層級結構沒有必然的聯系)
一般來說一個頁面中所有元素父級參照物都是body
center/inner/outer.offsetParent ----->body
document.body.offsetParent   //body是平面中的頂級是沒有父級參照物的

想要改變父級參照物需要脫離當前平面,需要通過position定位來進行改變
           position: relative;
           position: absolute;
           position: fixed;
           position: static;
           position:inherit;
absolute、relative、fixed任意一個值都能把父級參照物修改

offsetTop/offsetLeft:當前元素(外邊框)距離其父級參照(內邊框)物偏移距離
思考:不管center的父級參照物是誰,獲取其距離body的左偏移?
1、首先加上自己本身的左偏移
2、獲取自己的父級參照物(xx)把xx的左邊框和左偏移加上
3、基于當前的xx向上找父級參照物,找到后依然是累加邊框和其左偏移
4、一直找到父級參照物為null,一直找到body

Offset():和jq中的offset()方法相同,實現獲取頁面中任意一個元素,距離body的偏移(包含左偏移和上偏移),不管當前的父級參照物是誰。 

在標準的ie8瀏覽器中我們使用offsetLeft/offsetTop其實是是把父級參照物的邊框已經算在內了,所以我們不需要自己再單獨加邊框  
   function offset(curEle) {
        var totalleft = null;
        var totaltop = null;
        var par = curEle.offsetParent;
//      累加本身
        totalleft += curEle.offsetLeft;
        totaltop += curEle.offsetTop;
//        只要沒有找到body就把父級參照物的邊框和偏移進行累加
        while (par) {
//          不是ie8就累加邊框
            if(window.navigator.userAgent.indexOf('MSIE 8.0')==-1){
                //累加父級參照物的邊框
                totalleft+=par.clientLeft;
                totaltop+=par.clientTop;
            }
            //累加父級參照物的偏移
            totalleft+=par.offsetLeft;
            totaltop+=par.offsetTop;
            par=par.offsetParent;
        }
        return{
            left:totalleft,
            top:totaltop
        }
}

作業:
1、點擊滑動到文檔開始
2、圖片無縫滾動
3、文字上下/左右無縫滾動
4、手風琴效果
5、輪播
--------------------------------------------js同步與異步編程------------------------------------
Js是單線程------->可以想象它是一根筋,做著當前的這件事情,沒有完成之前絕對不會做下一件事情
Js中的兩種編程思想:同步和異步編程
同步編程------->只有上一件事情沒有完成,繼續處理上一件事情,只有上一件事情完成了,才會說做下一件事情(js中大部分是同步編程的)

異步編程:規劃做一件事情,但是不是當前立馬去執行這件事情,需要等待一定的時間,這樣的話,我們不會等著他執行,而是繼續執行下面的操作,只有當下面的事情都處理完成了,才會返回頭處理之前的事情,如果下面的事情并沒有處理完成,不管之前的事情有沒有到時間,都會踏踏實實的等它執行完。

在js中異步編程只有四種情況:
1、定時器都是異步編程
2、所有的事件綁定都是異步編程的
3、Ajax讀取數據的時候
4、回調函數也是異步編程

每一個瀏覽器對于定時器的等待時間都有一個最小值,谷歌是5~6ms,IE10~14ms,如果設置的等待時間小于這個值不起作用,還是需要等待最小的時間才執行的,尤其是寫0也不立即執行

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容