美文网首页
盒子模型

盒子模型

作者: 田成力 | 来源:发表于2019-10-11 17:15 被阅读0次

    js盒子模型

    提供一些属性和方法用来描述当前盒子的样式的

    client

    clientWidth/clientHight

    当前盒子可视区域的宽度和高度
    可视区域:内容的宽高+padding
    clientWidth=width+padding(left/right)
    clientHight=height+padding(top/bottom)

    和内容是否已出以及我们是否设置了overflow:hidden;没有关系
    clientTopclientLeft
    clientTop:盒子上边框的高度。
    clientLeft:盒子左边框的宽度。
    获取的结果就是border-width的值

    通过js盒子模型属性获取的结果是不带单位的,而且只能是整数(他会自动四舍五入)
    [图片上传失败...(image-44f587-1570785313950)]

    获取当前页面一屏幕的宽度
    document.documentElement.clientWidth||document.body.clientWidth
    
    获取当前页面一屏幕的高度
    document.documentElement.clientHeight||document.body.clientHeight
    
    

    面试题:让一个盒子水平垂直居中?不知道盒子宽度和高度如何处理?

    css:
    知道盒子宽高时
    [图片上传失败...(image-63d655-1570785313950)]
    不知道盒子宽高时(不兼容ie低版本浏览器)
    [图片上传失败...(image-57feda-1570785313950)]
    使用css3的flex伸缩盒模型(不兼容)
    [图片上传失败...(image-545a5c-1570785313950)]

    js:获取当前盒子具体的left/top值
    [图片上传失败...(image-e4c527-1570785313950)]

    offset

    offsetWidthoffsetHeight
    在clientWidth和clientHeight的基础上加上盒子的边框即可
    offsetWidth=width+padding(左右)+border(左右)=clientHeight+border(左右)
    在真实项目中想获取一个盒子的宽度和高度,我们一般用offsetWidth而不是clientwidth,border也是盒子的一部分

    offsetParent:参照物
    offsetLeft:左偏移()
    offsetTop:上偏移
    offset系列(与溢出的内容无关)
    偏移:
    1.当前元素(边框以外)到参照物(边框以内)的距离
    2.获取偏移量,当前元素不一定要设成定位元素。
    3.当前元素找参照物的方式跟css里找参照物一样
    4.默认的参照物是body,但实际上到窗口左边和上边的距离,body是文档的代理人,对body不要设置margin,float等属性
    5.其他元素margin,float也会造成影响

    scroll

    scrollWidthscrollHeight

    没有内容溢出的情况:获取的结果和clientWidth和clientHeight是一样的
    有内容溢出的情况:真实内容的宽度或者高度(包含溢出的内容),加上左padding或者上padding。获取的结果是一个约等于值,每个浏览器由于对行高或者文字的渲染不一样,结果也是不一样的,是否设置了overflow对最后获取的结果也有影响
    [图片上传失败...(image-cbc9b0-1570785313950)]
    scrollLeft:横向滚动条卷出去的宽度
    scrollTop:纵向滚动条卷出去的高度。
    最大宽、高 等于= 整个文档(scrollwidth/height)宽、高,减去一屏的(clientwidth/height)宽、高
    scrollTop=scrollheight-clientheight
    scrollLeftscrollTop是13个js盒子模型相关属性里唯一两个可以赋值的属性,其他的11个属性只能获取不能赋值,

    通过js盒模型属性获取值的特点

    • 1.若赋值是浮点数取得是整数部分,不会四舍五入
    • 2.13个js盒子模型获取的值都不带单位
    • 3.获取的结果都是复合样式值(好几个元素的样式组合在一起的值),如果只想获取单一样式值(例如只想获取padding)我们的盒子模型属性就操作不了了(这不能说没有用,真实项目中有时候我们就是需要获取组合的值来完成一些操作)

    在js中获取元素具体的样式值

    通过js盒子模型属性获取的结果都是盒子的组合样式值,不能直接获取某一个具体样式值,例如就想获得左padding
    curEle.style.xxx
    获取当前元素所有写在行内样式上的样式值
    特殊:只有把样式写在行内样式上,才可以通过这种办法获取到(写在其他地方的样式获取不到)所以这种办法在真实项目中使用非常少。
    window.getComputedStyle/currentStyle
    只要当前元素在页面中显示出来我们就可以获取样式值,也就是获取所有经过浏览器计算过的样式
    window.getComputedStyle:适用于标准浏览器,低版本IE浏览器不兼容,所以用curEle.currentStyle来获取需要的样式值。
    [图片上传失败...(image-2ef0a6-1570785313950)]
    [图片上传失败...(image-7fc29d-1570785313950)]
    [图片上传失败...(image-a88a73-1570785313950)]
    [图片上传失败...(image-daf800-1570785313950)]
    [图片上传失败...(image-795616-1570785313950)]
    [图片上传失败...(image-7a3dad-1570785313950)]
    [图片上传失败...(image-5bba7a-1570785313950)]

    设置元素样式属性
    加单位(符合加单位)
    [图片上传失败...(image-f40e17-1570785313950)]
    [图片上传失败...(image-7f8b17-1570785313950)]
    [图片上传失败...(image-4f8bef-1570785313950)]
    加单位(排除不需要加单位的)
    [图片上传失败...(image-2ab4d4-1570785313950)]

    批量给当前元素设置css样式
    [图片上传失败...(image-9180c7-1570785313950)]
    必须和setCss一起使用。

    封装css属性

     var css = function () {
            var len = arguments.length;
            fn = getCss;
            len > 3 ? fn = setCss : (len === 2 && Object.prototype.toString.call(arguments[1]) === '[object Object]' ? fn = setGroupCss : null);
            return fn.apply(this.arguments);}
    
    

    考虑兼容性方法

    考虑兼容性方法:

    try{}catch(e){};
    判断属性的方式"getComeputedStyle"in window,window.getComeputedStyle
    检测数据类型,instanceOf,
    Object.prototype.tostring.call
    检测浏览器的方式
    /MSIE[6-8]\.0/.test(navigator.userAgent)

    拖拽

    原理
    [图片上传失败...(image-d94834-1570785313950)]

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="../../reset.min.css">
        <style type="text/css">
            html, body {
                height: 500%;
                -webkit-user-select :none;
            }
            .dialogMark {
                position: fixed;
                top: 0;
                left: 0;
                z-index: 100;
                width: 100%;
                height: 100%;
                background: rgba(0, 0, 0, .3);
            }
            .diaLogBox {
                /*控制盒子在中间我们最好在js中实现,经过精密的计算,计算出具体的top和left而不是模糊的百分比这样我们在js中通过*/
                width: 200px;
                position: fixed;
                height: 300px;
                background: #FFF;
                z-index: 101;
                overflow: hidden;
            }
            .diaLogBox h3 {
                position: relative;
                padding: 0 10px;
                height: 50px;
                line-height: 50px;
                background: #DDD;
                border-bottom: 1px solid #aaaaaa;
                cursor: move;
            }
            .diaLogBox h3 i {
                position: absolute;
                right: 10px;
                top: 50%;
                margin-top: -10px;
                width: 20px;
                height: 20px;
                line-height: 20px;
                text-align: center;
                font-size: 16px;
                color: #E01D20;
                font-style: normal;
                font-family: "Microsoft JhengHei";
                background: lightgoldenrodyellow;
            }
        </style>
    
    </head>
    <body>
    <!--dialog:模态框-->
    
    <div class="dialogMark"></div>
    <div class="diaLogBox" id="diaLogBox">
        <h3 class="title">大力出奇迹
             <i class="closeBtn">X</i>
        </h3>
        <div class="con">
    
        </div>
    </div>
    <script>
        let dialogRender = (function () {
            let diaLogBox = document.getElementById('diaLogBox');
            let title = diaLogBox.getElementsByTagName('h3')[0];
             let closeBtn=diaLogBox.getElementsByTagName('i')[0];
            let winW = document.documentElement.clientWidth || document.body.clientWidth;
            let winH = document.documentElement.clientHeight || document.body.clientHeight;
    
            let maxL = winW - diaLogBox.offsetWidth;
            let maxT = winH - diaLogBox.offsetHeight;
            let Down = function (ev) {
                console.log(1);
                ev = ev || window.event;
                //记录鼠标起始位置&&盒子的起始位置
                this.strX = ev.clientX;
                this.strY = ev.clientY;
                this.strL = diaLogBox.offsetLeft;
                this.strT = diaLogBox.offsetTop;
                //谷歌下不兼容,用setCapture,releaseCapture解决鼠标焦点丢失问题
                if(this.setCapture){
                    this.onmousemove=Move;
                    this.onmouseup=Up;
                    this.setCapture();
                    return;
                }
    
    
                //按下代表拖拽开始,会有鼠标丢失的问题,
    //            this.onmousemove=Move;
    //            this.onmouseup=Up;
                //解决方法:
                //用document解决鼠标焦点丢失问题
                //let _this = this;
                document.onmousemove = (ev) => {
                    Move.call(this,ev);
                };
                document.onmouseup = (ev) => {
                    Up.call(this,ev);
                }
            };
            let Move = function (ev) {
    //            console.log(this);
                ev = ev || window.event;
                let curL = ev.clientX - this.strX + this.strL;
                let curT = ev.clientY - this.strY + this.strT;
    
                console.log(curT, ev.clientY, this.strY, this.strT);
                //边界处理
                curL = curL < 0 ? 0 : (curL > maxL ? maxL : curL);
                curT = curT < 0 ? 0 : (curT > maxT ? maxT : curT);
                console.log(curT);
                diaLogBox.style.left = curL + 'px';
                diaLogBox.style.top = curT + 'px';
    
                console.log(diaLogBox.style.top);
            };
            let Up = function (ev) {
               //谷歌下不兼容,用setCapture,releaseCapture解决鼠标焦点丢失问题
                if(this.setCapture){
                    this.onmousemove=null;
                    this.onmouseup=null;
                    this.releaseCapture();
                    return;
                }
                //用document解决鼠标焦点丢失问题
                document.onmousemove = null;
                document.onmouseup = null;
            };
            
      closeBtn.onclick=function () {
                diaLogBox.style.display='none';
            };
    
            return {
                init: function () {
                    //让盒子处于页面中间
                    diaLogBox.style.left = maxL / 2 + 'px';
                    diaLogBox.style.top = maxT / 2 + 'px';
                    title.onmousedown = Down;
                }
            }
        })();
        dialogRender.init();
    
    </script>
    </body>
    </html>
    
    

    弹性盒子

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="../../reset.min.css">
        <style type="text/css">
            html, body {
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
            #box {
                position: absolute;
                width: 200px;
                height: 200px;
                top: 100px;
                left: 100px;
                background: red;
                cursor: move;
            }
        </style>
    </head>
    <body>
    
    <div id="box">
    </div>
    <script src="发布订阅subscribe.js"></script>
    <script>
        let box = document.querySelector('#box');
        let subscribeDown = new Subscribe();
        let subscribeMove = new Subscribe();
        let subscribeUp = new Subscribe();
        let down = function (ev) {
            this.strX = ev.clientX;
            this.strY = ev.clientY;
            this.strT = this.offsetTop;
            this.strL = this.offsetLeft;
            //解决鼠标焦点丢失
            this.MOVE = move.bind(this);
            this.UP = up.bind(this);
            document.addEventListener('mousemove', this.MOVE);
            document.addEventListener('mouseup', this.UP);
            subscribeDown.fire(this, ev);
        };
        let move = function (ev) {
            this.curL = ev.clientX - this.strX + this.strL;
            this.curT = ev.clientY - this.strY + this.strT;
            this.style.left = this.curL + 'px';
            this.style.top = this.curT + 'px';
            subscribeMove.fire(this, ev)
        };
        let up = function (ev) {
            //抬起清除事件
            document.removeEventListener('mousemove', this.MOVE);
            document.removeEventListener('mouseup', this.UP);
            subscribeUp.fire(this, ev);
        };
        box.onmousedown = down;
    
        subscribeMove.add((curEle, ev) => {
            if (!curEle.lastFly) {
                curEle.lastFly = curEle.offsetLeft;
                curEle.speedFly = 0;
                return;
            }
            curEle.speedFly = curEle.offsetLeft - curEle.lastFly;
            curEle.lastFly = curEle.offsetLeft;
    
        });
        subscribeUp.add((curEle, ev) => {
            let minL = 0;
            let maxL = document.documentElement.clientWidth - curEle.offsetWidth;
            let speed = curEle.speedFly;
            let dir = 'right';
            speed < 0 ? dir = 'left' : null;
            speed = Math.abs(speed);
            curEle.flyTimer = setInterval(() => {
    
                if (speed < 0.5) {
                    clearInterval(curEle.flyTimer);
                    return;
                }
                speed *= 0.98;
                let curL = curEle.offsetLeft;
                if (dir === 'right') {
                    if (curL >= maxL) {
                        curEle.style.left = maxL + 'px';
                        dir = 'left';
                        return;
                    }
                    curL += speed;
                } else {
                    if (curL <= minL) {
                        curEle.style.left = minL + 'px';
                        dir = 'right';
                        return;
                    }
                    curL -= speed;
                }
                curEle.style.left = curL + 'px';
    
            }, 17);
        });
        subscribeDown.add((curEle, ev) => {
            clearInterval(curEle.flyTimer);
            curEle.speedFly = 0;
            clearInterval(curEle.dropTimer);
    
        });
        subscribeUp.add((curEle, ev) => {
            let speed = 9.8;
            let minT = 0;
            let maxT = document.documentElement.clientHeight - curEle.offsetHeight;
            flag = 0;
            curEle.dropTimer = setInterval(() => {
                if (flag > 1) {
                    clearInterval(curEle.dropTimer);
                    return;
                }
                speed += 9.8;
                speed *= 0.98;
                let curT = curEle.offsetTop;
                curT += speed;
                if (curT >= maxT) {
                    curEle.style.top = maxT + 'px';
                    speed *= -1;
                    flag++;return;
                }
                if (curT <= minT) {
                    curEle.style.top = minT + 'px';
                    speed *= -1;
                    return;
    
                }
                curEle.style.top = curT + 'px';
                flag = 0;
    
            }, 17);
        });
        
    </script>
    </body>
    </html>
    
    

    相关文章

      网友评论

          本文标题:盒子模型

          本文链接:https://www.haomeiwen.com/subject/qucxmctx.html