css&&js盒模型

108 阅读5分钟

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
那么子元素的附送啥的也就失效了