CSSOM handler

每次都记不住CSS BOM的API,太多了,所以总结几个常用的即可。默认不考虑IE9以下的浏览器。

渲染模式

compatmode(一般用于浏览器兼容) **document.compatMode**用来判断当前浏览器采用的渲染方式(兼容模式)。渲染即解释html,css,js之类的代码,从而给网页添加样式 兼容模式:只影响宽度和高度,但会影响浏览器和网页的大小,如clientwidth,scrollwidth,不涉及就不用考虑。 - BackCompat:标准兼容模式关闭。BackCompat Standards-compliant mode is not switched on. (Quirks Mode即表示怪异模式) - CSS1Compat:标准兼容模式开启。CSS1Compat Standards-compliant mode is switched on. (Standards Mode即表示标准模式) Standards Mode和Quirks Mode是有很大差别的,在Standards Mode下对于盒模型的解释和其他的标准浏览器是一样,但在Quirks Mode模式下则有很大差别,而在不声明Doctype的情况下,IE默认又是Quirks Mode。所以为兼容性考虑,我们可能需要获取当前的文档渲染方式。 故可以视为IE为Quirks Mode,其他浏览器为standard mode 当document.compatMode等于BackCompat时,浏览器客户区宽度是document.body.clientWidth; 当document.compatMode等于CSS1Compat时,浏览器客户区宽度是document.documentElement.clientWidth。

以上为参考的内容,但目前是以HTML5模式渲染,即都以标准模式渲染那,所以并什么无参考价值。

实际测试

对几个属性实际测试:

document.body.clientWidth  
document.documentElement.clientWidth  
// 上面获取的宽度是一样大的,浏览器都兼容

document.body.scrollTop    // chrome 支持这个 ,FF不支持,IE不支持  
document.documentElement.scrollTop;  // chrome 不支持 , FF支持,IE支持

document.body.scrollHeight  // 这个又都支持


那么通过模式document.compatMode判断是不可取的。
所以针对每个属性还是的分别HACK。通过对scrollTop的测试,可以表明是内核的差异造成了这个问题。

节点相对浏览器

https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

rect is a DOMRect object with six properties: left, top, right, bottom, width, height
可以获取元素相对浏览器的位置,其大小。

 Ele.getBoundingClientReact()

整个页面已滚动距离

第一种方法: 注意浏览器差异

var scrollTop = Math.max(document.body.scrollTop,document.documentElement.scrollTop);  
// 做个判断即可,解决兼容性问题

当然可以设置大小,那么页面会滚动到指定位置。

或者第二种:兼容性更好

window.pageXOffset  
window.pageYOffset  
// 为只读属性,不可设置大小。

节点在页面中绝对位置

一: offsetTop 是获取相对上层元素的距离,所以不断循环,获取总的大小。

function getElementTop(element) {  
  var actualTop = element.offsetTop;
  var current = element.offsetParent;
  while (current !== null) {
    actualTop += current.offsetTop;
    current = current.offsetParent;
  }
  return actualTop;
}

二:通过相对位置+ 滚动距离;考虑到性能问题,当然时选择第二种方法啦。但是要注意的是:打开页面后如果滚动,再刷新,那么还是在原来的位置,那么绝对位置就不正确了。判断现在相对位置的正负做加减。

var X= this.getBoundingClientRect().left+ window.pageXOffset;  // 考虑兼容  
var Y =this.getBoundingClientRect().top+ window.pageYOffset  

整个页面的长宽

即可以滚动的距离

document.body.scrollHeight  document.documentElement.scrollHeight  
document.body.scrollWidth   document.documentElement.scrollWidth  
上面都可用

可视区域宽高

即可以看见的页面的宽高:(除去浏览器的状态栏、控制台这些)

// 页面可视区域的宽高
var viewWidth = (typeof window.innerWidth === "number") ? window.innerWidth : document.documentElement.clientWidth;  
var viewHeight = (typeof window.innerHeight === "number") ? window.innerHeight : document.documentElement.clientHeight;

document.body.clientWidth  也可以获取到,但是要注意的是浏览器差异。  

整个视口大小

包括状态栏,控制台这些:

window.outWidth  
window.outHeight  

原生的方法

var x = document.getElementById('test');  
x.scrollIntoView();  

其余的一些属性和方法,并不常用,就不多做说明。

简单的封装

export let cssom = {  
    // get node adsolute position to the whole page
    absPosition(x) {
        return x.getBoundingClientRect().top < 0 ? window.pageYOffset - Math.abs(x.getBoundingClientRect().top) : window.pageYOffset + x.getBoundingClientRect().top
    }
    readScrollY() {
        return window.pageYOffset || document.documentElement.scrollLeft || document.body.scrollLeft
    }
    setScrollY(y) {
        document.documentElement.scrollLeft = y
        document.body.scrollLeft = y
    }
    scrollHeight() {
        return document.body.scrollHeight || document.documentElement.scrollHeight
    }
    viewHeight() {
        return (typeof window.innerHeight === "number") ? window.innerHeight : document.documentElement.clientHeight;
    }
    // use this to extend other methods
}

参考: