1 CSS盒子模型
- 定义:CSS盒子模型:由四部分构成:手动设置的宽高+padding+border+margin
2 JS中的盒子模型
- 目的:通过元素身上提供的属性和方法,来获取元素身上的样式;
- 分类:client系列、offset系列、scroll系列
- 注意:获取的值都没有单位,只是数值;
2.1 client系列--可视区域
- 包括:clientWidth clientHeight clientLeft clientTop
- clientWidth:手动设置的宽度+左右padding
- clientHeight:手动设置的高度+上下padding
- clientLeft:左边框的宽度;
- clientTop:上边框的宽度;
- 浏览器页面可视区域的宽高
- 宽度:document.documentElement.clientWidth || document.body.clientWidth;
- 高度:document.documentElement.clientHeight || document.body.clientHeight;
2.2 offset系列--偏移量
- 包括:offsetWidth offsetHeight offsetLeft offsetTop offsetParent
- offsetWidth: 手动设置的宽度+左右padding+左右border;
- offsetHeight: 手动设置的高度+上下padding+上下border;
- offsetLeft: 元素的左外边框距离它父级的左内边框之间的距离;
- offsetTop: 元素的上外边框距离它父级的上内边框之间的距离;
- offsetParent: 定位上的父级;查找到离它最近的添加定位元素的元素
2.3 scroll系列--卷帘
- 包括:scrollWidth scrollHeight scrollLeft scrollTop
- scrollWidth:
- 内容没有溢出的情况下,等于自己设定的宽度+左右padding,跟clientWidth相等;
- 内容溢出的情况下,约等于自己设定的宽度+左padding,约等于是因为不同浏览器获得的值不同;
- scrollHeight:
- 内容没有溢出的情况下,等于自己设定的高度+上下padding,跟clientHeight相等;
- 内容溢出的情况下,约等于自己设定的高度+上padding,约等于是因为不同浏览器获得的值不同;
- scrollLeft:指当前页面被浏览器卷去的宽度,有滚动条时,滚动卷去的宽度;
- scrollTop:指当前页面被浏览器卷去的高度,有滚动条时,滚动卷去的高度;
- scrollWidth:
2.4 JS盒子模型遇到的问题
- JS盒子模型中求出来值都是四舍五入后的整数,无法拿到小数——不解决;
- JS盒子模型中拿到的值都是复合值,无法拿到元素身上单独的宽或高属性;——解决:封装getCss
- 关于盒子模型的偏移量,只能求出当前容器的外边框到定位父级内边框之间的距离,无法求出当前定位元素到body的距离;——解决:封装offset
- 求可视区的宽高或被浏览器卷去的高度和宽度,代码太长,太麻烦;——封装win;
3 JS中常见的封装思想
- 封装的基本思想
- 属性判断:点; 得到的结果是,有值或undefined,配合if判断,返回的是布尔值;
-
obj.xxx
如:if(window.getComputedStyle)->boolean;
-
-
typeof obj.xxx=="function"
如:if(typeof window.getComputedStyle==="function");
-
- 属性判断:in; 得到的结果是布尔值,配合if判断;
- 代码:
"属性名" in 对象
;如:if("getComputedStyle" in window),返回布尔值
- 代码:
- 存在报错:用try...catch(e)...方法
- 正则判断:获取浏览器详细信息str,判断里面是否存在字符
MSIE 6/7/8.0
,利用正则查找返回相应的值;- 获取浏览器的信息:
var str=window.navigator.userAgent
; - 判断条件:
MSIE 6/7/8.0
; - 利用正则表达式来匹配多个满足情况的字符串,正则表达式为:
reg=/MSIE (6|7|8)\.0/gi
;- reg.test(str);返回布尔值
- str.search(reg)===-1;如果搜索到,则返回下标值,如果未搜索到,则返回-1;与indexOf方法相同,只不过indexOf方法只能查找一种字符,而正则可以查找多个;
- 获取浏览器的信息:
- 总结:就是利用两种方法来满足不同浏览器存在的问题;
- 利用
if...else..
方法来解决两种不同情况下的选择问题,而条件就是布尔值;- 1)属性判断:实质是判断属性是否存在;分为两种,目的是获取布尔值;适用于不同浏览器对同一属性支持情况不同;
- 第一种,利用属性判断,来获取布尔值,其中点得到的结果是:有值或者undefined,添加if会被强制转换为布尔值;
- 第二种,利用in来判断,得到的结果就是布尔值;
- 2)正则表达式判断:实质是判断浏览器种类;分为两种方法,目的是获取布尔值;适用于不同浏览器对一个属性支持,但是属性在不同浏览器中的表现形式不同,所以需要判断浏览器种类;
- 获取浏览器种类的代码:
var str=window.navigator.userAgent
,window可以省略; -
indexOf
方法,查找字符,来判断不同的浏览器;缺点是:只能查找一个特定字符,不能查找一类字符; -
test()
方法,利用正则表达式来查找一类字符,返回值为布尔值; -
search()
方法,同样利用正则表达式来搜索一类字符,找到则返回下标值,找不到则返回-1,所以判断条件为str.search(reg)===-1
,返回值也是布尔值;
- 获取浏览器种类的代码:
- 1)属性判断:实质是判断属性是否存在;分为两种,目的是获取布尔值;适用于不同浏览器对同一属性支持情况不同;
- 利用
try...catch(e)..
方法来解决,报错的问题,只要报错就可以用此方法;当不报错的情况下,执行try语句,报错的情况下,执行catch语句;
- 利用
- 属性判断:点; 得到的结果是,有值或undefined,配合if判断,返回的是布尔值;
- 实例:获取元素身上的属性的两种方法解析
- getComputedStyle()方法,是window的属性,属性值为函数;
- 代码:
getComputedStyle(oDiv,null).width
,其中第一个参数为元素,第二个参数可以是任何值,没有含义,一般设置为null,width为元素身上的属性; - 兼容性:标准浏览器(包括IE9/10/11)支持;IE5/6/7/8浏览器不支持,会报错;
- 代码:
- currentStyle属性,是元素身上的属性;
- 代码:
oDiv.currentStyle.width
,其中oDiv为元素,width为元素身上的属性; - 兼容性:IE浏览器(包括IE9/10/11)都支持;标准浏览器(Chrome)不支持,会报错;
- 代码:
- 总结:出现报错可以用
try...catch(e)...
方法,以上方法配合使用;- 代码:
<script> //封装兼容的方法获取oDiv元素身上的width属性 //第一种方法: try{ console.log(getComputedStyle(oDiv,null).width); }catch(e){ console.log(oDiv.currentStyle.width); } //第二种方法: try{ console.log(oDiv.currentStyle.width); }catch(e){ console.log(getComputedStyle(oDiv,false).width); } </script>
- getComputedStyle()方法,是window的属性,属性值为函数;
4 getCss封装
- 需求:获取元素身上的属性值
- 知识点:
- 不同浏览器获取属性值的方法不同,封装兼容的方法,使用if...else...或try...catch...方法;
- 获取的属性值分为几类,1)数字加单位,如200px,属性名为width;2)单词,如solid,属性名为borderStyle;3)二进制颜色值,如#fff,属性名为backgroundColor;等
- 获取的属性值不能是复合值,如background,padding,border等;
- 针对一些兼容性不同的属性,如透明度,在标准浏览器中设置为
opacity:0.1
,在IE6-8浏览器下设置为:filter:alpha(opacity=10)
,所以在不同浏览器下获取属性名时会不同;
- 思路:
- 基本封装:标准浏览器下使用getComputedStyle()方法,IE6-8浏览器下使用currentStyle方法;
- 升级1:获取数字加单位中的数字,需要去掉单位:有效数字的判断+单位;其中单位可以是px,em,rem,pt等;
- 升级2:透明度兼容问题,所以获取属性时会存在差异,需要针对不同的浏览器下进行分别获取,在标准浏览器下,直接获取opacity属性值,在IE6-8浏览器下,实际求filter的值,如果filter的值输入正确,返回对应的数值,数值一定要除上100,如果透明度书写错误,则透明度无法设置成功,返回默认1;
<script> var oDiv=document.getElementsByTagName("div")[0]; function getCss(ele,attr){ var value=null; //利用try...catch...方法来兼容不同浏览器 /*try{ value=getComputedStyle(ele,null)[attr]; }catch(e){ value=ele.currentStyle[attr]; }*/ if(window.getComputedStyle){ //在标准浏览器(包括IE9,10)下,window.getComputedStyle属性值为一个函数,强制转换为布尔值为true value=getComputedStyle(ele,null)[attr]; }else{ //在IE6,7,8浏览器下,不支持getComputedStyle属性,会返回undefined,转换为布尔值为false; //添加对透明的判断 if(attr=="opacity"){ //还要判断透明度代码是否书写正确,书写错误设置不成功,返回1; var reg1=/^alpha\(opacity=(\d+)\)$/;//此时绝对不能加全局g,否则test和exec会对lastIndex值进行重复影响; value=ele.currentStyle.filter; return reg1.test(value) ? reg1.exec(value)[1]/100 : 1; //如果reg1添加全局g,会出现问题,可以通过RegExp.$1来获取小分组的内容 //代码:return reg1.test(value)? RegExp.$1/100 : 1; } value=ele.currentStyle[attr]; } //升级1 将获取的属性值为200px格式的值,去掉单位,只输出数字,其他类型的不变 //判断条件为:有效数字,如+-200.343px; var reg=/^(([+-]?(\d|([1-9]\d+)))(\.\d+)?)(px|em|rem|pt)$/; return reg.test(value) ? parseFloat(value) : value; //升级2 针对不同浏览器兼容不同,如透明度的设置,在不同浏览器下设置的代码不同,想要获取其中的数值 //思路:在标准浏览器下获取属性名opacity,在IE6-8浏览器下,获取属性名filter,在利用正则获取其中的数值,需要除上100; } console.log(getCss(oDiv,"height"));//属性名要加双引号; console.log(getCss(oDiv,"borderStyle"));//结果为solid; console.log(getCss(oDiv,"opacity"));//结果为0.5; </script>
网友评论