• js脚本化css


    脚本化CSS

    我们刚讲过如何获取和设置行内样式的值,但是我们开发不会所有样式都写在行内,同时js没法获取内嵌样式表和外部样式表中的值.

    事实上DOM提供了可靠的API,得到计算后的样式。

    1. 获取计算样式表

    只读,不可写
    获取的值是计算后的绝对值,不是相对值

    window.getComputedStyle(ele,null).attr IE8以上
    ele.currentStyle IE8及其以下

    例子:

    window.getComputedStyle(ele).attr
    // 当然window是可以省略的
    getComputedStyle(ele).attr

    好用的东西,一定不兼容。所以IE6、7、8不兼容

    附加在元素身上的currentStyle属性,它表现和style点语法一样,使用驼峰式访问

    例子

    oDiv.currentStyle.width

    之前讲过,点操作符必须符合标识符的规范,所以使用点操作符获取有连字符的属性要写成驼峰式

    getComputedStyle(oDiv).backgroundColor;
    oDiv.currentStyle.backgroundColor;

    中括号操作符,因为中括号内写字符串,所以不用遵循标识符规范,就可以保留连字符的写法

    getComputedStyle(oDiv)['background-color'];
    oDiv.currentStyle['background-color'];

    颜色值在高级浏览器中是rgb()格式,低级浏览器中就是原样输出。

    示例:

    封装getStyle(dom,attr)兼容性

    实际上,老司机都不这么做。我们不关心你的版本是什么,我只关心你的能力。

    function getStyle(ele,attr){
    if(window.getComputedStyle){
    return getComputedStyle(ele)[attr];
    }else{
    return ele.currentStyle[attr];
    }
    }
    function getStyle(dom,attr){
    if(dom.currentStyle){ // IE8 及其一下
    return dom.currentStyle[attr]
    }else{
    return getComputedStyle(dom,null)[attr]
    }
    }

    现在我们要在一个轮子,就是封装一个函数,这个函数接收两个参数,第一个是对象,第二个是属性名。

    getStyle(obj,”padding-left”);
    getStyle(obj,”paddingLeft”);

    这个函数返回的是这个属性值的计算后的样式。更牛逼的是,我们无论用户输入的是驼峰还是非驼峰,都让这个函数鲁棒。

    2. 操作元素样式

    我们知道前面学过了如果设置样式通过行内style来设置元素样式,

    那么我们就可以通过获取计算样式值,然后修改

    var oBox = document.getElementById('box');
    var wid = parseInt(getStyle(oBox,'width'));
    oBox.onclick = function(){
    wid += 20;
    console.log(wid);
    oBox.style.width = wid + 'px';
    }

    3. 快捷位置和尺寸

    DOM已经提供给我们计算后的样式,但是还觉得不方便,所以DOM又提供给我们一些API:

    获取元素的显示尺寸(数字类型的值)

    ele.offsetWidth width+左右padding+左右border
    ele.offsetHeight height+上下padding+上下border
    ele.offsetLeft 水平距离 (常用)
    ele.offsetTop 竖直距离 (常用)
    ele.clientWidth width+左右padding (常用)
    ele.clientHeight height+上下padding (常用)
    dom.clientLeft 上边框的width (可不记)
    dom.clientTop 左边框的width (可不记)

    3.1. offsetWidth和offsetHeight

    全线兼容,是自己的属性,和别的盒子无关。

    一个盒子的offsetWidth值就是自己的 width+左右padding+左右border的宽度(说白就是盒子的大小)

    总结一下,全线兼容。

    3.2. offsetLeft属性和offsetTop

    这两个属性的兼容性非常差,不要着急,我们慢慢来看。

    IE9、IE9+、Chrome等高级浏览器:

    一个元素的offsetLeft值,就是这个元素左边框外,到自己的offsetParent对象的左边框内的距离

    每一个元素,天生都有一个属性,叫做offsetParent

    就是自己祖先元素中,离自己最近的已经定位的元素,如果自己的祖先元素中,没有任何盒子进行了定位,那么offsetParent对象就是body。

    op.offsetParent; // 查找离自己最近的定位父级

    无论这个盒子自己是否定位,自己的offsetParent就是按照上述方法寻找。

    IE6、IE7:

    IE6、7的offsetParent对象是谁,和高级浏览器有非常大的不同。

    情形1:自己如果没有定位属性,那么自己的offsetParent对象就是自己的祖先元素中离自己最近的有width或者有height的元素:

    <div class="box1">
    <div class="box2"> → 你好,我有宽度 , offsetParent
    <div class="box3"> → 你好,我没有宽高
    <p>p> → 你好,我没有定位
    div>
    div>
    div>

    情形2:自己如果有定位属性

    那么自己的offsetParent就是自己祖先元素中离自己最近的有定位的元素。

    <div class="box1">
    <div class="box2">
    <div class="box3"> → 你好,我没有宽高,有定位 , offsetParent
    <p>p> → 你好,我没有定位
    div>
    div>
    div>

    数值就是自己的左外边框到offsetParent对象的左内边框的值。

    IE8:

    IE8的offsetParent是谁呢?和高级浏览器一致:

    无论自己是否定位,自己的offsetParent就是自己祖先元素中,离自己最近的已经定位的元素。

    这一点,没有任何兼容问题!

    兼容性解决办法,不是能力检测,也不是版本检测,而是善用这个属性,要确保属性的使用条件:

    这样的话,所有浏览器的值都是一样的,offsetLeft、offsetTop值是number类型的,可以直接参与运算,不需要parseInt()

    3.3. clientWidth和clientHeight

    clientWidth就是自己的width+padding的值。 也就是说,比offsetWidth少了border。

    如果盒子没有高度,用文字撑的,IE6 clientHeight是0,其他浏览器都是数值

    以上6个属性要铭记于心,就offsetLeft、offsetTop比较闹腾,但是合理使用,也没兼容问题了

    3.4. clientLeft和clientTop

    这两个属性没有太大的意义就是上边框和左边看的宽度而已

    4. 获取元素的有定位属性的父级

    ele.offsetParent
    如果没有定位父节点,则返回body

    封装getElementPosition函数,获取元素相对于文档的坐标

    function getElePos(dom){ // 获取元素相对于文档的坐标
    var x = dom.offsetLeft;
    var y = dom.offsetTop;
    var parent = dom.offsetParent;
    while(parent !== null){
    x += parent.offsetLeft;
    y += parent.offsetTop;
    parent = parent.offsetParent;
    }
    return {
    x: x,
    y: y
    }
    }

    5. 获取元素的滚动值

    5.1 获取滚动元素的宽高

    当元素实际内容超过设置的内容时

    dom.scrollWidth ==> 元素实际内容的width
    dom.scrollHeight ==> 元素实际内容的height

    5.2 获取元素的滚动距离(数字类型的值)

    dom.scrollLeft 滚动的水平距离
    dom.scrollTop 滚动的竖直距离

    5.3 滚动距离的兼容写法

    • 获取滚动条的滚动距离 IE8以上

    window.pageXOffset 页面滚动的水平距离
    window.pageYOffset 页面滚动的竖直距离

    • 获取滚动条的滚动距离 IE8及其以下

    document.documentElement.scrollLeft IE7,8
    document.documentElement.scrollTop IE7,8
    document.body.scrollLeft
    document.body.scrollTop
    在IE8以上兼容性比较混乱,在使用时两个值相加,因为这两对值不能同时存在

    封装getScrollOffset兼容性函数

    function getScrollOffset(){
    if(window.pageYOffset){
    return {
    x: window.pageXOffset,
    y: window.pageYOffset
    }
    }else{
    return {
    x: document.documentElement.scrollLeft + document.body.scrollLeft,
    y: document.documentElement.scrollTop + document.body.scrollTop;
    }
    }
    }

    6. 获取浏览器窗口的尺寸

    IE8以上

    window.innerWidth 窗口的宽度(包含滚动条)
    window.innerHeight 窗口的高度(包含滚动条)

    IE8及其以下

    document.documentElement.clientWidth 标准模式下
    document.documentElement.clientHeight
    (在Chrome,Firefox,IE7,IE8不包含滚动条,在IE8以上包含滚动条)
    document.body.clientWidth 怪异模式下
    document.body.clientWidth

    检测浏览器是不是在怪异模式下

    dowument.compatMode === 'BackCompat'

    封装getViewportOffset兼容性函数

    function getViewportOffset(){
    if(window.innerWidth){
    return {
    x: window.innerWidth,
    y: window.innerHeight
    }
    }else{
    if( document.compatMode === 'BackCompat'){
    return {
    x: document.body.clientWidth,
    y: document.body.clientHeight
    }
    }else{
    return {
    x: document.documentElement.clientWidth,
    y: document.documentElement.clientHeight
    }
    }
    }
    }

    7. 设置滚动条的滚动距离

    浏览器页面滚动

    window.scrollTo(x,y) 让滚动条滚动到指定位置
    window.scrollBy(x,y) 让滚动条滚动指定距离

    页面元素滚动

    ele.scrollTo(x,y)
    ele.scrollBy(x,y)

    本文作者:二价亚铁

    本文链接:https://www.cnblogs.com/xw-01/p/18266103

    版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

  • 相关阅读:
    linux平台源码编译ffmpeg
    linux C.UTF-8和en-US.UTF-8语言环境有什么区别?(中文乱码问题)locale命令 centos、ubuntu修改编码集(没搞定!)
    Cisco简单配置(十三)—链路聚合
    【云原生之Docker实战】使用Docker部署FireShare轻量视频分享平台
    从这几个关键功能,带您认真了解低代码的世界~
    c++的字节序与符号位的问题
    小程序源码:猜歌喝酒小游戏多功能组合微信小程序源码下载
    shell之sed
    3.流的输入/输出
    直流有刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(二)
  • 原文地址:https://www.cnblogs.com/xw-01/p/18266103