浏览代码

jquery's width/height includes scrollbars now. use offsetWidth/offsetHeight/getBoundingClientRect instead, but that doesn't prevents us from having borders. adjust. fixes #3612

Adam Shaw 8 年之前
父节点
当前提交
c2753b9761
共有 4 个文件被更改,包括 35 次插入30 次删除
  1. 4 2
      src/util.js
  2. 14 12
      tests/automated/getClientRect.js
  3. 10 8
      tests/automated/getScrollbarWidths.js
  4. 7 8
      tests/lib/dom-utils.js

+ 4 - 2
src/util.js

@@ -199,6 +199,7 @@ function getOuterRect(el, origin) {
 // Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding.
 // Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
 // Origin is optional.
+// WARNING: given element can't have borders
 // NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
 function getClientRect(el, origin) {
 	var offset = el.offset();
@@ -235,10 +236,11 @@ function getContentRect(el, origin) {
 
 
 // Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element.
+// WARNING: given element can't have borders (which will cause offsetWidth/offsetHeight to be larger).
 // NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
 function getScrollbarWidths(el) {
-	var leftRightWidth = el.innerWidth() - el[0].clientWidth; // the paddings cancel out, leaving the scrollbars
-	var bottomWidth = el.innerHeight() - el[0].clientHeight; // "
+	var leftRightWidth = el[0].offsetWidth - el[0].clientWidth;
+	var bottomWidth = el[0].offsetHeight - el[0].clientHeight;
 	var widths;
 
 	leftRightWidth = sanitizeScrollbarWidth(leftRightWidth);

+ 14 - 12
tests/automated/getClientRect.js

@@ -9,24 +9,26 @@ describe('getClientRect', function() {
 		{ width: 100, height: 100 },
 		{ width: 100, height: 100 }
 	);
-	defineTests(
-		'when border',
-		{ border: '5px solid red' },
-		{ width: 100, height: 100 },
-		{ width: 100, height: 100 }
-	);
 	defineTests(
 		'when padding',
 		{ padding: '5px 10px' },
 		{ width: 100, height: 100 },
 		{ width: 120, height: 110 }
 	);
-	defineTests(
-		'when border and padding',
-		{ border: '5px solid red', padding: '5px 10px' },
-		{ width: 100, height: 100 },
-		{ width: 120, height: 110 }
-	);
+
+	//// getClientRect doesn't work with borders anymore
+	//defineTests(
+	//	'when border',
+	//	{ border: '5px solid red' },
+	//	{ width: 100, height: 100 },
+	//	{ width: 100, height: 100 }
+	//);
+	//defineTests(
+	//	'when border and padding',
+	//	{ border: '5px solid red', padding: '5px 10px' },
+	//	{ width: 100, height: 100 },
+	//	{ width: 120, height: 110 }
+	//);
 
 	function defineTests(description, cssProps, innerDims, dims) {
 		describe(description, function() {

+ 10 - 8
tests/automated/getScrollbarWidths.js

@@ -7,18 +7,20 @@ describe('getScrollbarWidths', function() {
 		'when margin',
 		{ margin: '5px 10px' }
 	);
-	defineTests(
-		'when border',
-		{ border: '5px solid red' }
-	);
 	defineTests(
 		'when padding',
 		{ padding: '5px 10px' }
 	);
-	defineTests(
-		'when border and padding',
-		{ border: '5px solid red', padding: '5px 10px' }
-	);
+
+	//// getScrollbarWidths doesn't work with borders anymore
+	//defineTests(
+	//	'when border',
+	//	{ border: '5px solid red' }
+	//);
+	//defineTests(
+	//	'when border and padding',
+	//	{ border: '5px solid red', padding: '5px 10px' }
+	//);
 
 	function defineTests(description, cssProps) {
 		describe(description, function() {

+ 7 - 8
tests/lib/dom-utils.js

@@ -17,16 +17,15 @@ function getStockScrollbarWidths(dir) {
 		})
 		.appendTo('body');
 
+	var elRect = el[0].getBoundingClientRect();
 	var innerEl = el.children();
-	var width = el.width();
-	var height = el.height();
-	var offset = el.offset();
-	var innerOffset = innerEl.offset();
+	var innerElRect = innerEl[0].getBoundingClientRect();
+
 	var girths = {
-		left: innerOffset.left - offset.left,
-		right: offset.left + width - innerOffset.left,
-		top: innerOffset.top - offset.top,
-		bottom: offset.top + height - innerOffset.top
+		left: innerElRect.left - elRect.left,
+		right: elRect.left + elRect.width - innerElRect.left,
+		top: innerElRect.top - elRect.top,
+		bottom: elRect.top + elRect.height - innerElRect.top
 	};
 
 	el.remove();