金色小芝麻

vuePress-theme-reco 金色小芝麻    2021 - 2023
金色小芝麻 金色小芝麻

Choose mode

  • dark
  • auto
  • light
主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
author-avatar

金色小芝麻

83

文章

27

标签

主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
  • 前端入门

    • 博客搭建过程及相关配置
    • 数组中的16种常用方法
    • JS中的数据类型简析——基本数据类型值
    • JS中的数据类型object基础
    • JS中三种常见的判断
    • 数据类型之间的区别(堆内存Heap VS 栈内存Stack)
    • JS基础练习题及解析
    • 开关灯的小案例
    • JS中数据类型检测方法——typeof
    • 条件判断几个小练习
    • JS循环——for循环
    • 自定义属性实现选项卡小案例
    • 字符串中的12种常用方法
    • DOM操作的简单原理
    • JS实现隔行变色鼠标跟随小案例
    • JS中function的基础知识
    • JS中数组去重的三种方法
    • JS中时间格式化的三种方法
    • JS中URL参数处理的三种方法
    • JS小案例——获取随机验证码
    • DOM操作之——获取DOM标签的9种方式
    • DOM操作之——DOM节点类型及属性
    • DOM操作之——元素的增删改、样式修改、插入内容
    • JS中THIS相关问题梳理
    • JS中的变量提升机制
    • 在全局:私有上下文中:带VAR和不带VAR的区别
    • 作用域和作用域链查找机制
    • JS中堆栈内存的释放问题
    • JS中的闭包机制
    • ES3和ES6定义变量的区别
    • JS中的单例和工厂设计模式
    • JS中的面向对象OOP理论基础
    • 构造函数创建自定义类
    • JS中的原型和原型链
    • Math中常用的9种方法
    • 从一道阿里经典面试题剖析函数三种角色
    • 重写内置call
    • 重写一个内置new
    • 浏览器渲染页面的主体流程
    • 减少DOM的回流和重绘
    • JS中的多种继承方式
    • JS中数据类型检测四种方式的优缺点
    • JS中的正则表达式&&全面梳理
    • 非严格模式 🆚 严格模式的区别
    • 数组方法reduce、filter、flat
    • 获取数组中最大值/最小值的三种基础方法
    • 轮播图——渐隐渐显版
    • 深克隆 VS 浅克隆|深比较 VS 浅比较|回调函数
    • 轮播图——左右切换版
    • 事件及事件绑定、事件对象及事件传播
    • 从在地址栏输入网址到看到页面的过程&&AJAX基础
    • 想自学JS吗?想提升JS底层原理吗?76张脑图带你彻底搞懂原生JS
    • 面试手写API系列
    • 30张脑图带你从零开始学VUE
    • JS中的盒子模型
    • 初识JS-基础中的基础
    • 前端发展简史
    • JS中的三大类输出方式

JS中的盒子模型

vuePress-theme-reco 金色小芝麻    2021 - 2023

JS中的盒子模型

金色小芝麻 2020-02-28

# 前言

  • 主要目的:
    • 由于目前掌握的获取元素样式的方法十分有限,所以盒子模型主要是用来获取元素的样式的(操作DOM)
  • 定义:
    • 基于一些属性和方法,让我们能够获取到当前元素的样式信息,例如:clientWidth 、offsetWidth等

# 属性

共计13种,分三个系列,分别是:client、offset、scroll。

# 一、client 系列

# 1、clientWidth / Height

  • 定义:获取盒子可视区域的宽高(内容宽度+左右 padding )
  • 特点:
    • 1.内容溢出与否对他无影响
    • 2.获取的结果是没有单位的(其余的盒模型属性也是)
    • 3.获取的结果是整数,它会自己进行四舍五入(其余的盒模型属性也是)
  • 使用:
    • box.clientWidth
    • box.clientHeight
  • 拓展:
    • 1、获取当前页面一屏幕(可视化)区域的宽高

      • 宽:let winW = document.documentElement.clientWidth || document.body.clientWidth;
      • 高:let winH = document.documentElement.clientHeight || document.body.clientHeight;
      • 注意:前面 documentElement 在低版本浏览器下不兼容
    • 2、利用JS实现盒子居中

      原理:(一屏幕的宽度-盒子的宽度)/2 === LEFT

# 2、clientLeft / Top

  • 定义:
    • box.clientLeft获取盒子左边框的大小
    • box.clientTop获取盒子上边框的大小

# 二、offset 系列

# 1、offsetWidth / Height

  • 定义:获取当前元素的总宽度/高度
    • 相当于在 client 的基础上加上 border == 盒子本身的宽高
  • 特点:(与 client 一致)
    • 1.内容溢出与否对他无影响
    • 2.获取的结果是没有单位的(其余的盒模型属性也是)
    • 3.获取的结果是整数,它会自己进行四舍五入(其余的盒模型属性也是)
  • 使用:
    • box.offsetWidth / Height

# 2、offsetLeft / Top

  • 定义:距离其父参照物的左偏移/上偏移(当前元素的外边框到父参照物的里边框)
  • 使用:
    • box.offsetLeft/Top

# 3、offsetParent

  • 定义:获取它的父参照物(不一定是父元素)
    • 父参照物和它的父元素没有必然的联系

父参照物查找:同一个平面中,最外层元素是所有后代元素的父参照物

  • 而基于 position:relative / absolute / fixed 可以让元素脱离文档流(一个新的平面),从而改变元素的父参照物
  • 通俗来说,也就是:元素的父级参照物在默认情况下都是body,如果给一个元素增加position属性(absolute,relative、fixed),会让他所有子孙元素的父级参照物都指向当前这个元素
  • 注意:
    • document.body.offsetParent === null;
  • 使用:
    • box.offsetParent
  • 拓展:
    • 封装一个方法获取一个元素距离body的左、上偏移量(不论其父参照物是谁)
/*
 * offset:获取当前元素距离BODY的左/上偏移(不论其父参照物是谁)
 *   @params
 *      curEle:current element当前要操作的元素
 *   @return
 *      [object]包含上/左偏移的信息  => {top:xxx,left:xxx} 
 */
function offset(curEle) {
    let par = curEle.offsetParent,
        l = curEle.offsetLeft,
        t = curEle.offsetTop;
    //存在父参照物,而且还没有找到BODY,BOBY的边框不做考虑的情况
    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
    };
}
  • 在不考虑IE8版本和body有边框的情况下可简写为
function offset(curEle) {
    let left = curEle.offsetLeft;
    let top = curEle.offsetTop;
    let parent = curEle.offsetParent;
    // 上来第一步先获取当前元素的偏移量和父级参照物
    while (parent !== document.body) {
        // 检测一下当前元素的父级参照物是不是body,如果不是就累加上父级参照物的边框的宽度和偏移量
        left += parent.clientLeft + parent.offsetLeft;
        top += parent.clinetTop + parent.offsetTop;
        // 在获取父级参照物的父级参照物,直到获取到body为止
        parent = parent.offsetParent;
        }
        return {
            left: left,
            top:top
        }
    }

# 三、scroll 系列

# 1、scrollWidth / Height

  • 定义:

    • 在没有内容溢出的情况下,获取的结果和 client 是一样的
    • 在有内容溢出的情况下,获取的结果约等于真实内容的宽高(左/上PADDING + 真实内容的宽度/高度)
  • 注意:

    在内容超出的情况下

    • 1.不同浏览器获取的结果不尽相同
    • 2.设置 overflow 属性值对最后的结果也会产生一定的影响
  • 使用:

    • box.scrollWidth
    • box.scrollHeight
  • 拓展:

    获取整个页面真实的高度

    • document.documentElement.scrollHeight || document.body.scrollHeight

# 2、box.scrollTop / Left

  • 定义:竖向 / 横向 滚动条卷去的高度
  • 特点:
    • 1.边界值
      • min = 0
      • max =(整个的高度scrollHeight) - (一屏幕高度clientHeight)

      利用边界值:

      • 1、快速定位到顶部:box.scrollTop=0;
      • 2、快速定位到底部:box.scrollTop = box.scrollHeight-box.clientHeight
    • 2.可读写
      • 13个盒子模型属性,只有这两个是“可读写”的属性(既可以获取也可以设置对应的值)
      • 其余的都是“只读”属性(不能设置值,只能获取)
  • 使用:
    • box.scrollTop
    • box.scrollLeft
  • 实例:
    • 回到顶部
// 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);//13~17ms动画兼容最好,IE最好用17
};

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

# 方法

# 一、getComputedStyle(获取CSS样式的最优方案)

  • 定义:获取当前元素所有经过浏览器计算过的样式
  • 特点:
    • 只要元素在页面中呈现出来,那么所有的样式都是经过浏览器计算的
    • 哪怕你没有设置和见过的样式也都计算了
    • 不管你写或者不写,也不轮写在哪,样式都在这,可以直接获取
  • 注意:在IE6~8浏览器中不兼容,需要基于currentStyle来获取
  • 语法:
    • window.getComputedStyle([ELEMENT],[伪类])
    • 第一个参数是操作的元素 / 第二个参数是元素的伪类:after/:before
    • 一般第二个参数都写 null 或不写
    • 获取的结果是CSSStyleDeclaration这个类的实例(对象),包含了当前元素所有的样式信息
  • 使用:
let styleObj = window.getComputedStyle([element],null);
styleObj["backgroundColor"];
styleObj.display;

# 二、currentStyle

  • 注意:与 getComputedStyle 一致,此方法用于IE6~8浏览器
  • 使用:styleObj = [element].currentStyle;

由于目前操作DOM逐渐被弱化,JS盒子模型逐渐被弱化

欢迎来到 金色小芝麻
看板娘