有三种方法能够确定浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)。
对于Internet Explorer、Chrome、Firefox、Opera 以及 Safari:
窗口显示区(可视区域)的宽度和高度,包括滚动条。
window.innerHeight - IE不支持该属性,IE中body元素的clientHeight属性与该属性相同。window.innerWidth – IE不支持该属性,IE中body元素的clientWidth属性与该属性相同。
对于 Internet Explorer 8、7、6、5:
窗口显示区(可视区域)的宽度和高度,不包括滚动条区域。
document.documentElement.clientHeight document.documentElement.clientWidth 或者 document.body.clientHeight document.body.clientWidth
对于元素宽度尺寸的获取,jquery提供了width方法。
对于文档级非普通元素window,document的宽度获取
$(window).width() 代表了当前浏览器可见区域的宽度 $(document).width() 则代表了整个文档的宽度,可以有滚动内容
window 反映的是视图窗口,没有用window.innerWidth(包括滚动条区域),而是采用window.document.documentElement.clientWidth(不包括滚动条区域),document是反映了实际内容区间,那么可以存在溢出滚动,所以就是:
document.documentElement.scrollWidth document.body.scrollWidth
由于兼容问题就取2者之中的最大值。
.width()是我们经常应用获取对象宽度的方法,但是就Query为了做这个兼容可不是表面上那么简单的,首先整理下涉及到元素宽度处理,我们需要考虑的因素。
1 元素的宽素可以是内联或者通过link定义,所以通过style是不可取的 2 元素在隐藏状态下是不能获取任何尺寸的 display:none 3 CSS3引入了box-sizing的设置
我们看看jquery如何处理的:
width,height在内部最终调用的是jQuery.css(elem, type, extra)方法,jQuery.css是最终的一个针对所有CSS处理的接口,我们放在下一章,这里我们只涉及width与height的获取。
display:none的状态下是无法获取元素的尺寸的,所以jQuery在最开始之前必须要检测下这个状态,这个处理是通过钩子jQuery.cssHooks['widht'].get方法调用的:
/^(none|table(?!-c[ea]).+)/test(jQuery.css(elem, "display")) //代码很简单通过判断得到的值
当检测到是none的情况下,就要把display置为block?不行这样就改变了布局的原意了,本来就是隐藏的。jQuery就会对元素增加position: absolute; visibility: hidden;
这样的属性达到display:none的效果,因为在visibility: hidden
的情况下,是可以获取到值的,只是对于用户不可见而已。
获取元素的尺寸值我们有offsetWidth,与offsetHeight,大多情况下是够用了,但是有一种情况如果元素采用boxSizing处理,所以jQuery还要对BorderBox情况的检测,如果如果是采用了border-box样式的话,针对值的获取还要减去padding,border,这又是一个相当繁琐的过程,我们在之前就提到过这个过程的处理了。
<!doctype html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <script src="http://code.jquery.com/jquery-latest.js"></script> <title>jQuery.width</title> <style type="text/css"> div{ width: 3000px; height: 100px; } </style> </head> <body> <div style="background:red;border:20px solid #ccc;">获取元素大小</div> <button id="test1">display:none状态下,无法获取</button> <button id="test2">模拟jQuery的.width()方法,在隐藏的时候也能获取</button> <ul></ul> <script type="text/javascript"> var div = document.querySelectorAll('div')[0] $('#test1').click(function(){ div.style.display = "none"; show('隐藏状态下div.style.width: '+ div.style.width) show('隐藏状态下div.offsetWidth: '+ div.offsetWidth) }) //获取样式合集 function getStyles(elem) { return elem.ownerDocument.defaultView.getComputedStyle(elem, null); }; //交换样式 function swap(elem, options, callback, args) { var ret, name, old = {}; for (name in options) { old[name] = elem.style[name]; elem.style[name] = options[name]; } ret = callback.apply(elem, args || []); for (name in options) { elem.style[name] = old[name]; } return ret; }; //获取当前样式 function curCSS(elem,name) { var computed = getStyles(elem); var ret = computed.getPropertyValue(name) || computed[name]; return ret; } //获取宽高 function getWidthOrHeight(elem, name, extra){ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight; //需要extra判断是否是content/border的处理 //代码太长,这里省略了,具体可以可以参考jQuery的源码 return val; } var cssShow = { display: "block", position: "absolute", visibility: "hidden" } $('#test2').click(function(){ var elem = div; function width() { if( /^(none|table(?!-c[ea]).+)/.test(curCSS(div, 'display')) ){ return swap(elem, cssShow, function() { return getWidthOrHeight(elem, 'width', 'content'); }) } } show('模拟jQuery.width的处理: '+ width()) }) function show(data){ $('ul').append('<li>'+ data +'</li>') } </script> </body> </html>