css&&js盒模型

Betsy_迪發表於2019-02-22

css盒子模型

css&&js盒模型

js盒模型

css&&js盒模型

  • clientWidth/clientHeight:當前盒子可視區域的寬度和高度(不包括邊框,也就是內容的寬高加padding)
  • clientHeight=height+padding(top/bottom)
  • clientWidth=Width+padding(left/right) 和我們是否溢位以及我們是否設定了overflow:hidden沒有關係
//->獲取當前頁面一螢幕的寬度(加或者是為了相容所有瀏覽器)
document.documentElement.clientWidth||document.body.clientWidth

//->獲取當前頁面一螢幕的高度
document.documentElement.clientHeight||document.body.clientHeight
複製程式碼

盒模型的分類

盒模型分為兩類: IE盒模型和標準盒模型。 兩者的區別在於:

IE盒模型的width/height = content + border + padding
標準盒模型的width/height = content
複製程式碼

面試題:讓一個盒子在整個頁面水平和垂直都居中的位置?如果不知道盒子寬度和高度如何處理?

css

//->使用定位
.box{
  position:absolute;
  top:50%;
  left:50%;
  margin:-50px 0 0 -100px;
  width:200px;
  height:100px;
  }
  
  
複製程式碼
//->也是使用定位的方式,但是不知道盒子具體寬高(不相容IE低版本)

.box{
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  margin:auto;
  width:200px;
  height:200px
  }
  
複製程式碼
//->使用CSS3伸縮盒模型(不相容),移動端經常使用,但是安卓低版本瀏覽器不相容
html{
height:100%
}

body{
  display:flex;
  align-items:center;
  justify-content:center;
  height:100%;
  margin:auto;
  }
  
  .box{
   width:200px;
   height:200px;
   background:red
   }
 
  
複製程式碼

js

var winW=document.documentElement.clientWidth||document.body.clientWidth;
var winH=document.documentElement.clientHeight||document.body.clientHeight;
var boxW=box.clientWidth;
var boxH=box.clientHeight;
box.style.left=(winW-boxW)/2+'px';
box.style.top=(winH-boxH)/2+'px';
複製程式碼

clientTop/clientLeft

只要top和left,沒有right和bottom這兩個屬性

clientTop:盒子上邊框的高度

clientLeft:左邊框的寬度

獲取的結果其實就是border-width的值

通過JS盒子模型屬性獲取的結果是不帶單位的。而且只能是正數(他會自動四捨五入)

offsetWidth/offsetHeight

在clientTop/clientLeft的基礎上叫盒子模型的邊框即可

和內容的是否溢位沒有關係

真實專案中,獲取一個盒子的寬度和高度。我們一般用offsetWidth(而不是clientWidth'),border也算是當前盒子的一部分

offsetParent:當前盒子的父級參照物

offsetTop和offsetLeft:當前盒子距離其父級參照物的偏移(上偏移和左偏移)

在JS中獲取元素具體的樣式值

通過JS 盒子模型屬性獲取的結果都是盒子的組合樣式值,不能直接獲取某一個具體樣式,例如:我就想獲取左padding..

cueEle.style.xxx

獲取當前元素所有寫在行內樣式上的樣式值

特殊:只有把樣式寫在行內樣式上,才可以通過這種辦法獲取到(寫在其他地方的樣式是獲取不到的)

這種辦法在真實專案中使用的特別少,因為我們不可能把所有樣式都寫在行內上(這樣要內嵌式和外鏈式就沒有用了)

只要當前元素在頁面中顯示出來,我們就可獲取其樣式值(不管寫在行內還是樣式表中)也就是獲取所有經過瀏覽器計算過的樣式(當前元素只要能在當前頁面中展示,那麼他的所有樣式都是經過瀏覽器計算的,包含一些沒有計算的,包含一些你沒有設定,瀏覽器按照預設樣式渲染的樣式)

window.getComputedStyle:適用於標準瀏覽但是在IE678下不相容,我們使用curEle.currentStyle來獲取需要的樣式值

//通過getComputedStyle獲取的結果是一個物件,物件中包含了所有被瀏覽計算過的樣式屬性及屬性值,如果要獲取一個就在後面寫一箇中括號屬性名或者點屬性名
window.getComputedStyle([當前要操作的元素],null)[這裡放要查詢的屬性名];(IE678不相容)

//在低版本瀏覽器中我們可以使用currentStyle
[當前元素].currentStyle  ==>結果也是一個物件
例如:box.currentStyle.paddingLeft
複製程式碼
/*
 * getCss:獲取當前元素某一個樣式屬性值
 * @parameter:
 *    curEle:當前需要操作的元素
 *    att:當前需要獲取的樣式屬性名
 *  @return
 *    獲取的樣式屬性值
*/
function getCss(){
}
複製程式碼
function get(curEle ,attr){
var value=null;
if('getComputedStyle' in window){
value=window.getComputedStyle(curEle,null)[attr];}else{
value=curEle.currentStyle[attr];}return value;}

複製程式碼

優化封裝getCss方法

//優化封裝getCss方法
function getCss(curEle, attr) {
    var value = null;
    //=>獲取樣式值
    if ('getComputedStyle' in window) {
        value = window.getComputedStyle(curEle, null)[attr];
    } else {
        //=>IE6~8下處理透明度
        if(attr==='opacity'){
            value=curEle.currentStyle['filter'];
            //=>把獲取的結果轉換為opacity一樣的結果filter:alpha(opacity=20)
            var reg=/^alpha\(opcity=(.+)\)$/;
            reg.test(value)?value=reg.exec(value)[1]/100:value=1;
        }else{
            value = curEle.currentStyle[attr];
        }
    }
    //=>去除獲取值的單位
    var temp = parseFloat(value);
    !isNaN(temp) ? value = temp : null;
    return value;
}
複製程式碼
封裝設定css的屬性方法
var setCss = function (curEle, attr, value) {
        if (attr === 'opacity') {
            curEle['style']['opacity'] = value;
            curEle['style']['filter'] = 'alpha(opacity=' + value * 100 + ')';
            return;
        }
        !isNaN(value) && !/^(zIndex|zoom|lineHeight|fontWeight)$/i.test(attr) ? value += 'px' : null;
        curEle['style'][attr] = value;
    };
複製程式碼
//setting style attribute values to current elements in batches
 var setGroupCss = function (curEle, options) {
        if (Object.prototype.toString.call(options) !== '[object Object]') return;
        for (var attr in options) {
            if (options.hasOwnProperty(attr)) {
                setCss(curEle, attr, options[attr]);
            }
        }
    };
複製程式碼
//integrated method of setting styles, obtaining styles and setting styles in batches
var css = function () {
        var len = arguments.length,
            type = Object.prototype.toString.call(arguments[1]),
            fn = getCss;
        len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null);
        return fn.apply(this, arguments);
    };
複製程式碼
  var offset = function (curEle) {
        var l = curEle.offsetLeft,
            t = curEle.offsetTop,
            p = curEle.offsetParent;
        while (p.tagName !== 'BODY') {
            if (!/MSIE 8/i.test(navigator.userAgent)) {
                l += p.clientLeft;
                t += p.clientTop;
            }
            l += p.offsetLeft;
            t += p.offsetTop;
            p = p.offsetParent;
        }
        return {top: t, left: l};
    };
複製程式碼
var winBox = function (attr, value) {
        if (typeof value !== 'undefined') {
            document.documentElement[attr] = value;
            document.body[attr] = value;
            return;
        }
        return document.documentElement[attr] || document.body[attr];
    };
複製程式碼
var children = function (curEle, tagName) {
        var result = [],
            childList = curEle.childNodes;
        for (var i = 0; i < childList.length; i++) {
            var item = childList[i];
            if (item.nodeType === 1) {
                if (typeof tagName !== 'undefined') {
                    if (item.tagName.toLowerCase() === tagName.toLowerCase()) {
                        result.push(item);
                    }
                    continue;
                }
                result.push(item);
            }
        }
        return result;
    };
複製程式碼
 var queryElementsByClassName = function queryElementsByClassName(strClass,context) {
        if (arguments.length === 0) return [];
        context=context||document;
        var nodeList = utils.toArray(context.getElementsByTagName('*'));
        strClass = strClass.replace(/^ +| +$/g, '').split(/ +/);
        for (var i = 0; i < strClass.length; i++) {
            var reg = new RegExp('(^| +)' + strClass[i] + '( +|$)');
            for (var k = 0; k < nodeList.length; k++) {
                if (!reg.test(nodeList[k].className)) {
                    nodeList.splice(k, 1);
                    k--;
                }
            }
        }
        return nodeList;
    };
複製程式碼

自適應佈局(面試基本都會問)

左邊100px,右邊200px,中間自適應

<div class='main'>
<div class='left'></div>
<div class='center'></div>
<div class='right'></div>
</div>

css(用伸縮盒模型方式佈局):
.main{
    display:flex
}
.left{
    width:100px;
    height:100px;
    background:red
}
.center{
    flex:1
}
.right{ width:200px;
    height:100px;
    background:red
}

一旦父級元素設定了disaply:flex
那麼子元素的附送啥的也就失效了

複製程式碼

相關文章