JS盒子模型常用属性

JS盒子模型常用属性

CSS如下:

<style type="text/css">
    *{
        margin: 0;
        padding: 0;
    }
    #box{
        margin: 100px;
        padding: 30px;
        width: 200px;
        height: 200px;
        border: 30px solid royalblue;
    }
</style>

HTML如下:

<body>
<div id="box"  class="test00 test01 test02 test03" name="aaa" index="0">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut corporis facere libero nulla numquam possimus provident quae quisquam. Accusantium commodi culpa dolores esse excepturi maxime praesentium recusandae sapiente sit voluptates.
</div>
</body>

小技巧:自动生成随机文本

使用方法:在div元素中书写lorem或lorem + 单词数量 (不加单词数量则生成默认长段随机文本)

使用这个功能可以帮助我们生成随机文本,不必费力的去找填充文本。

Lorem ipsum,中文又称“乱数假文”, 是指一篇常用于排版设计领域的拉丁文文章 [1] ,主要的目的为测试文章或文字在不同字型、版型下看起来的效果。

Lorem ipsum从西元15世纪开始就被广泛地使用在西方的印刷、设计领域中,在电脑排版盛行之后,这段被传统印刷产业使用几百年的无意义文字又再度流行。由于这段文字以“Lorem ipsum”起头,并且常被用于标题的测试中,所以一般称为Lorem ipsum,简称为Lipsum。 ---参考百度百科

1、JS盒子模型指的是通过JS中提供的一系列属性和方法,获取页面中元素的样式信息值

<script>
    var box = document.getElementById('box');
    console.dir(box);
</script>
360截图20181009151847113.png

div#box(这个元素有很多自己的私有属性)通过这个元素所属的类的原型找到原型链上公共的属性和方法。

原型链如下:
div#box => HTMLDivElement.prototype => HTMLElement.prototype => Element.prototype =>Node.prototype => EvenTarget.prototype => Object.prototype

1) Element.attributes

Element.attributes 属性返回该元素所有属性节点的一个实时集合。该集合是一个 NamedNodeMap 对象,不是一个数组,所以它没有 数组 的方法,其包含的 属性 节点的索引顺序随浏览器不同而不同。更确切地说,attributes 是字符串形式的名/值对,每一对名/值对对应一个属性节点。


360截图20181009191203176.png
NamedNodeMap

NamedNodeMap 接口表示属性节点 Attr 对象的集合。尽管在 NamedNodeMap 里面的对象可以像数组一样通过索引来访问,但是它和 NodeList 不一样,对象的顺序没有指定。

NamedNodeMap 对象是即时的(live),因此,如果它内部包含的对象发生改变的话,该对象会自动更新到最新的状态。


无标题.png

也就是说attributes属性除了拥有自己的属性,还继承了它内置类NameNodeMap上的方法。

走一个测试下这些方法

  1. NamedNodeMap.getNamedItem(属性名) 通过属性名获取属性节点(Attr)。
    box.attributes.getNamedItem('name')
    //=>  name='aaa'
  1. NamedNodeMap.item() 通过索引获取属性节点(Attr),或者,当索引超出或等于属性节点的数量时,返回 null。
    box.attributes.item(0)
    //=> id='box'
  1. NamedNodeMap.removeNamedItem(属性名) 移除一个属性节点(Attr)。
box.attributes.removeNamedItem('id')       //名为id的属性节点被删除
  1. NamedNodeMap.setNamedItem(node) 替换或添加一个属性节点(Attr)到映射(map)中。

如果此节点已存在,则将替换该节点,并返回被替换的节点,否则返回值是 null。

//创建属性节点
var typ = document.createAttribute('id');
//添加属性值
typ.nodeValue = 'box';
//添加属性节点到元素上
box.attributes.setNamedItem(typ);

2) classList 和className

360截图20181009202759317.png

classList 和className的区别

Element.classList 是一个只读属性,返回一个元素的类属性的实时DOMTokenList 集合。
使用 classList 是替代element.className作为空格分隔的字符串访问元素的类列表的一种方便的方法。

className 获取或设置指定元素的class属性的值。

  • 设置新的class属性值会把原先的覆盖掉
    let cName = elementNodeReference.className;
    
    elementNodeReference.className = cName;
  • cName是一个字符串变量,表示当前元素的class属性的值,可以是由空格分隔的多个class属性值.

Element.classList 的方法

add( String [, String] )
添加指定的类值。如果这些类已经存在于元素的属性中,那么它们将被忽略。

box.classList.add('test004')

remove( String [,String] )
删除指定的类值。

box.classList.remove('test001')

client系列(当前元素的几个私有属性)

clientWidth / clientHeight 内容宽度/高度 + 左右/上下填充(也就是padding值)

内容的宽度和高度:我们设置的width和height这两个样式就是内容的宽度和高度,如果没设置height值,容器高度会根据里面的内容自适应,这样获取的值就是真实内容的宽度和高度。
如果设置了height值,不论内容多了还是少了,内容的高度就是设置的height值

真实内容的宽度和高度:代指的是内容的实际宽高(和我们设置的width和height没有必然的联系)
比如:只设置容器width=200px ;height=200px,如果里面的放了10万个字,就会内容溢出,而height还是原来的height,等于200px;那么文字内容就等于它溢出的高度+容器设置height值。

<style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        #box{
            margin: 100px;
            padding: 30px;
            width: 200px;
            /*height: 200px;*/
            border: 30px solid royalblue;
        }
    </style>
</head>
<body>
<div id="box" class=" " name="aaa" index="0">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut corporis facere libero nulla numquam possimus provident quae quisquam. Accusantium commodi culpa dolores esse excepturi maxime.
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus at cupiditate delectus, eligendi excepturi explicabo, harum illum maxime minima minus quae quibusdam ratione saepe, sunt suscipit temporibus ullam vero voluptatibus.
</div>
<script>
    var box = document.getElementById('box');
    console.log(box.clientWidth);      // = > 260
    console.log(box.clientHeight);    // => 480
</script>
</body>
360截图20181009214016680.png
无标题111.png

clientLeft 和 clientTop

clientLeft:左边框的宽度 clientTop:上边框的高度 (就是border[left/top]Width)

3)offset系列

offsetWidth / offsetHeight

offsetWidth = clientWidth + clientLeft*2 ( 左右边框宽度)
offsetHeight = clientWidth + clientTop*2 ( 上下边框高度)

offsetParent

当前元素的父级参照物

offsetLfet / offsetHeight

当前元素的外边框距离父级参照物的内边框的偏移量

4)scroll系列

scrollWidth / scrollHeight

和clientWidth / clientHeight 一样(前提是:容器中内容没有溢出的情况下)

如果容器中的内容溢出,我们获取的结果如以下规则:
scrollWidth:真实内容的宽度(包含溢出)+ 左填充(padding-left)
scrollWidth:真实内容的高度(包含溢出)+ 上填充(padding-top)
获取到结果都是约等于的值
容器是否设置overflow=‘hidden’对于最终的结果是有影响的;在不同浏览器中获取的结果也不是相同的

360截图20181009232511396.png

scrollLeft / scrollTop

表示滚动条卷去的宽度/高度

201810110729.png

关于JS盒子模型的取值问题

如果宽度/高度设置值带有小数位,用这13个属性去获取值,不会出现小数,都会四舍五入取整

360截图20181010000238443.png

关于操作浏览器本身的盒子模型信息

document.documentElement.clientWidth / document.documentElement.clientHeight
是当前浏览器可视窗口的宽度和高度(一屏幕的宽度和高度)

document.documentElement.scrollWidth / document.documentElement.scrollWidth
是当前页面的真实宽度和高度【所有屏加起来(也就是页面很长出现了滚动条)的宽度和高度,是一个约等于值】

操作浏览器盒子模型的方法

兼容性比较好的写法
document.documentElement[attr] || document.body[attr];
document.documentElement[attr] 必须写在前面,[attr]表示要获取或设置的属性
例如:获取滚动条卷去页面的高度scrollHeight
document.documentElement.scrollHeight || document.body.scrollHeight;

//如果只传递了attr没有传value,默认“获取”
//如果两个参数都传递了,则为“设置”

代码如下:

function win(attr,value) {
        if (typeof  value === 'undefined'){
            return document.documentElement[attr] || document.body[attr];   // [attr]表示属性名
        }
        document.documentElement[attr] = value;
        document.body[attr] = value;
    }

获取元素的某一个具体的样式的属性值需要注意事情

1、元素.style.属性名

这中方式需要把元素的样式都写在行内样式上才可以(写在样式中是不管用的)

2、使用window.getComputedStyle()

Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有CSS属性的值。 私有的CSS属性值可以通过对象提供的API或通过简单地使用CSS属性名称进行索引来访问。

可以简单理解为,获取所有经过浏览器计算过的样式集合

语法

let style = window.getComputedStyle(element, [pseudoElt]);
比如:window.getComputedStyle(el,null).color

参数element

用于获取计算样式的Element

参数pseudoElt

指定一个要匹配的伪元素的字符串。必须对普通元素省略(或null)。null 的意思是不返回伪类元素

返回的style是一个实时的CSSStyleDeclaration对象,当元素的样式更改时,它会自动更新本身。
CSSStyleDeclaration 表示一个CSS属性键值对的集合。CSSStyleDeclaration也是由window.getComputedStyle()返回的只读接口

浏览器兼容性

在IE6~8 下不兼容,因为window下没有getComputedStyle这个属性,可以使用currentStyle来获取
语法:ele.currentStyle.attr
官方的提醒:该特性是非标准的,请尽量不要在生产环境中使用它!

【方法使用】使用window.getComputedStyle()获取伪元素属性的值

HTML如下:

<div class="box">
    <p id="boxp">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam animi, at aut consequatur doloribus expedita facere hic libero pariatur, quae quibusdam tempora temporibus totam unde voluptatum! Amet debitis eius tenetur?
    </p>
</div>

CSS如下:

       *{
            margin: 0;
            padding: 0;
            font-family: sans-serif;
            font-size: 14px;
        }
        .box{
            margin:20px auto;
            width:300px;
            padding: 20px;
            border: 1px dashed #cccccc;
        }
        .box p{
            line-height: 1.5;
        }
        /*:before :after ->在一个元素标签的前面或者后面,创建一个新的虚拟标签
           可以给这个虚拟的标签增加样式和内容。
        */
        .box p:before{
            display: block;
            height: 30px;
            line-height: 30px;
            text-align: center;
            content: 'lorem';
            background: royalblue;
            color: #ffffff;
        }
        .box p:after{
            display: block;
            height: 30px;
            line-height: 30px;
            text-align: center;
            content: 'lorem';
            background: royalblue;
            color: #ffffff;
        }

JS如下:

 var boxp = document.getElementById('boxp');
window.getComputedStyle(boxp, 'after').content = 'hello 123' ; //=> Uncaught DOMException: Failed to set the 'content' property on 'CSSStyleDeclaration'
//报错:CSSStyleDeclaration是一个CSS属性键值对的集合,只读接口不允许修改CSS属性的值
console.log(window.getComputedStyle(boxp, 'after').content);    // => "lorem"

【方法使用】 获取当前元素所有经过浏览器计算过的样式中的[attr]对应的值

1、使用try、catch来处理兼容
前提:必须保证try中的代码块在不兼容浏览器中执行的时候报错,才可以用catch捕获到异常信息,进行其它处理,不管是什么浏览器,都需要先执行try中的代码块(消耗性能)

function getCss(curEle, attr) {
        var val = null;
        try {
            val = window.getComputedStyle(curEle,null)[attr];
        }catch(e){
            val = curEle.currentStyle[attr];
        }
        return val;
    }

2、判断当前浏览器中是否存在这个属性或者方法

 function getCss(curEle, attr) {
        var val = null;
        if ('getComputedStyle' in window) {
            val = window.getComputedStyle(curEle,null)[attr];
        }else {
            val = curEle.currentStyle[attr];
        }
        return val;
    }

3、获取到当前的浏览器是IE6~8

function getCss(curEle, attr) {
        var val = null;
        if (/MSIE (6|7|8)/.test(navigator.userAgent)) {
            val = curEle.currentStyle[attr];
        }else {
            val = window.getComputedStyle(curEle,null)[attr];
        }
        return val;
    }

改进1.0:把获取的样式值单位去掉

 function getCss(curEle, attr) {
        var val = null;
        if ('getComputedStyle' in window) {
            val = window.getComputedStyle(curEle,null)[attr];
        }else {
            val = curEle.currentStyle[attr];
        }
        return parseFloat(val);  //return parseFloat(val)  对于某些样式属性的值是不能去掉单位的,例如:float、position、margin、padding、border这些复合值、background...
    }
function getCss(curEle, attr) {
        var val = null, reg = null;
        if ('getComputedStyle' in window) {
            val = window.getComputedStyle(curEle, null)[attr];
        } else {
            val = curEle.currentStyle[attr];
        }
        reg = /^(-?\d+(\.\d+)?)(px|pt|rem|em)$/;
        return reg.test(val) ? parseFloat(val) : val;
    }

改进2.0:解决某些样式属性在不同浏览器中不兼容问题,比如:opacity

function getCss(curEle, attr) {
        var val = null, reg = null;
        if ('getComputedStyle' in window) {
            val = window.getComputedStyle(curEle, null)[attr];
        } else {
            if (attr === 'opacity') {
                val = curEle.currentStyle['filter'];
                reg = /^alpha\(opacity=(\d+(?:\.\d+)?)\)$/i;
                val = reg.test(val)?reg.exec(val)[1]/100:1;
            }else {
                val = curEle.currentStyle[attr];
            }
        }
        reg = /^(-?\d+(\.\d+)?)(px|pt|rem|em)$/;
        return reg.test(val) ? parseFloat(val) : val;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容