6. JS盒子模型操作_计算样式

元素的style下的属性,默认为空字符串,可以通过getComputedStyle(element).属性,获取到的结果为带单位的字符串;如下:

document.onclick = function () {
    box.style.height = '100px';
    // 获取box的宽度
    console.log(box.style.width);  // 空 
    console.log(getComputedStyle(box).height);  // 100px
}

基于一些属性和方法,让我们能够获取到当前元素的样式信息,
例如:

  • client:
    • width/height
    • top/left
  • offset
    • width/height
    • top/left
    • parent
  • scroll
    • width/height
    • top/left

1、client(不带单位)

  • 获取盒子可视区域的宽高(支持padding,不包含边框)
    clientWidth
    clientHeight
  1. 内容溢出与否对它无影响;
  2. 获取的结果是没有单位的(其余的盒模型属性也是);
  3. 获取的结果是整数,它会自己进行四舍五入(其余的盒模型属性也是);
  • 获取盒子左边框和上边框的大小
    clientLeft
    clientTop
    边框尺寸
    getComputedStyle(box3).borderTopWidth 边框尺寸

  • 获取当前页面一屏幕(可视化)区域的宽高

let winW = document.documentElement.clientWidth || document.body.clientWidth;
let winH = document.documentElement.clientHeight || document.body.clientHeight;
image.png

2、Offset

1、获取盒子可视区的宽高(内容宽度+左右padding+左右border)
offsetWidth
offsetHeight
在client的基础上加上border== 盒子本身的宽高

  • offsetTop:距离其父参照物的上偏移
  • offsetLeft:距离其父参照物的左偏移(当前元素的外边框到父参照物的里边框)
  • offsetParent:获取它的父参照物(不一定是父元素)

getBoundingClientRect()当前元素到页面可视区的尺寸、距离
注意:是跟滚动条走的。
width/height/left/right/top/bottom/x/y

父参照物和它的父元素没有必然的联系,父参照物查找:同一个平面中,最外层元素是所有后代元素的父参照物,而基于position:relative/absolute/fixed 可以让元素脱离文档流(一个新的平面),从而改变元素的父参照物
document.body.offsetParent === null

3、scroll

scrollWidth
scrollHeight

  • 在没有内容溢出的情况下,获取的结果和client是一样的

  • 在有内容溢出的情况下,获取的结果约等于真实内容的宽高(上/左padding + 真实内容的高度/宽度)

    • 1.不同浏览器获取的结果不尽相同
    • 2.设置overflow属性值对最后的结果也会产生一定的影响;
      获取整个页面真实的高度
      document.documentElement.scrollHeight || document.body.scrollHeight
  • box.scrollTop
  • box.scrollLeft
let box = document.getElementById('box');
//=>竖向滚动条卷去的高度
//=>横向滚动条卷去的宽度
//1.边界值
//min=0
//max=整个的高度scrollHeight - 一屏幕高度clientHeight
box.scrollTop
box.scrollLeft

//=>13个盒子模型属性,只有这两个是“可读写”的属性(既可以获取也可以设置对应的值),其余的都是“只读”属性(不能设置值,只能获取)
box.scrollTop=0;

4、滚动条的距离

  • 滚动条的距离,只能读不能写
    window.pageYOffset/window.pageXOffset
    window.scrollTo(x,y) 专门用来写滚动条距离的
  • 滚动条的距离,既能读也能写(document.documentElement=HTML)
    document.documentElement.scrollTop
document.onclick = function(){
    console.log(window.pageYOffset)
    console.log(document.documentElement.scrollTop)
    console.log(document.documentElement.scrollLeft)
    document.documentElement.scrollTop = 0; // => NO
    window.scrollTo(0,300); //=> yes
}

5、获取浏览器的尺寸

window.innerWidth/window.innerHeight
注意:
window.innerWidth/window.innerHeight如果有滚动条,会计算滚动条距离;1280
document.body.clientWidth(浏览器的尺寸,排除滚动条的) 1263

绝对位置

<script>
/*
* offset:获取当前元素距离BODY的左/上偏移(不论其父参照物是谁)
*   @params
*      curEle:current element当前要操作的元素
*   @return
*      [object]包含上/左偏移的信息  => {top:xxx,left:xxx} 
* by LYR on 2019/01/01
*/
function offset(curEle) {
    let par = curEle.offsetParent,
        l = curEle.offsetLeft,
        t = curEle.offsetTop;
    //存在父参照物,而且还没有找到BODY
    while (par && par.tagName !== "BODY") {
        //在原有偏移的基础上累加:父参照物的边框、父参照物的偏移
        if (!/MSIE 8\.0/.test(navigator.userAgent)) {
            //IE8中偏移值自已就算了边框了,不需要我们在加边框的值 navigator.userAgent获取当前浏览器的版本信息
            l += par.clientLeft;
            t += par.clientTop;
        }
        l += par.offsetLeft;
        t += par.offsetTop;
        //继续获取上级参照物
        par = par.offsetParent;
    }
    return {
        top: t,
        left: l
    };
}
</script>

回到顶部

<body>
    <a href="javascript:;" id="link" class="link">回到顶部</a>

    <script>
        let HTML = document.documentElement,
            LINK = document.getElementById('link');

        // 1.当浏览器滚动条滚动的时候,我们进行验证:卷去的高度超过两屏,我们让#LINK显示
        function check() {
            //winH:一屏幕高度  scrollT:卷去的高度
            let winH = HTML.clientHeight,
                scrollT = HTML.scrollTop;
                LINK.style.display = scrollT >= winH * 2 ? 'block' : 'none';
        }
        window.onscroll = check;

        // 2.点击回到顶部
        LINK.onclick = function () {
            /* 让按钮隐藏 */
            LINK.style.display = 'none';
            //先禁止滚动事件触发(因为在回到顶部的运动过程中,如果事件一直在,会计算按钮显示隐藏的样式,无法让按钮隐藏)
            window.onscroll = null;

            /* 实现动画 */
            let step = 1000;
            let timer = setInterval(() => {
                //每一次获取最新的SCROLL-TOP值,在现有的基础上减去步长,让其走一步
                let curT = HTML.scrollTop;
                if (curT === 0) {
                    //边界判断:已经回到顶部后,我们清除定时器
                    clearInterval(timer);
                    //恢复滚动条滚动的监听事件
                    window.onscroll = check;
                    return;
                }
                curT -= step;
                HTML.scrollTop = curT;
            }, 17);
        };


        //SET-INTERVAL:设置一个定时器(TIMER代表这个定时器),每间隔INTERVAL这么久,就会把FUNCTUION执行一次...一直到手动清除定时器为止
        // let timer = setInterval([FUNCTUION], [INTERVAL]);
        // clearInterval(timer);
    </script>
</body>

延迟加载

/*
 * offset:获取当前元素距离BODY的左/上偏移(不论其父参照物是谁)
 *   @params
 *      curEle:current element当前要操作的元素
 *   @return
 *      [object]包含上/左偏移的信息  => {top:xxx,left:xxx} 
 * by LYR on 2019/01/01
 */
function offset(curEle) {
    let par = curEle.offsetParent,
        l = curEle.offsetLeft,
        t = curEle.offsetTop;
    while (par && par.tagName !== "BODY") {
        if (!/MSIE 8\.0/.test(navigator.userAgent)) {
            l += par.clientLeft;
            t += par.clientTop;
        }
        l += par.offsetLeft;
        t += par.offsetTop;
        par = par.offsetParent;
    }
    return {
        top: t,
        left: l
    };
}


/*
 * 图片完全显示出来的条件 
 *   A:盒子底边距离BODY(页面最顶端)的距离:盒子的高度+盒子距BODY的上偏移
 *   B:浏览器底边距离BODY的距离:一屏幕的高度 + 卷去的高度
 *   A<=B:盒子就完全出现在用户的视野中
 * 让图片显示
 *   获取图片TRUE-IMG属性的值,赋值给SRC属性,当图片能正常加载出来后,让图片显示即可
 */
let imgBox = document.querySelector('.imgBox'),
    _img = imgBox.querySelector('img');

//=>显示图片 
//curImg:要显示的图片
function lazyImg(curImg) {
    //给SRC赋值真实的图片地址
    let trueImg = curImg.getAttribute("trueImg");
    curImg.src = trueImg;
    //校验图片是否能够正常加载出来:IMG.ONLOAD事件用来监听图片是否能加载
    curImg.onload = function () {
        curImg.style.display = 'block';
    };
    //=>设置自定义属性:isLoad存储当前图片已经加载过了
    curImg.isLoad = true;
}

//=>监听页面滚动事件(不论基于什么方式,只要页面滚动了,则触发事件)
window.onscroll = function () {
    //=>已经加载过就不要在重复加载了
    if (_img.isLoad) return;

    let HTML = document.documentElement,
        B = HTML.clientHeight + HTML.scrollTop,
        A = imgBox.offsetHeight + offset(imgBox).top; //=>当前案例中,获取距离BODY的上偏移完全可以imgBox.offsetTop,因为父参照物就是BODY
    if (A <= B) {
        //=>符合图片显示的条件了
        lazyImg(_img);
    }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348