get-size.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*!
  2. * getSize v2.0.3
  3. * measure size of elements
  4. * MIT license
  5. */
  6. /* jshint browser: true, strict: true, undef: true, unused: true */
  7. /* globals console: false */
  8. ( function( window, factory ) {
  9. /* jshint strict: false */ /* globals define, module */
  10. if ( typeof define == 'function' && define.amd ) {
  11. // AMD
  12. define( factory );
  13. } else if ( typeof module == 'object' && module.exports ) {
  14. // CommonJS
  15. module.exports = factory();
  16. } else {
  17. // browser global
  18. window.getSize = factory();
  19. }
  20. })( window, function factory() {
  21. 'use strict';
  22. // -------------------------- helpers -------------------------- //
  23. // get a number from a string, not a percentage
  24. function getStyleSize( value ) {
  25. var num = parseFloat( value );
  26. // not a percent like '100%', and a number
  27. var isValid = value.indexOf('%') == -1 && !isNaN( num );
  28. return isValid && num;
  29. }
  30. function noop() {}
  31. var logError = typeof console == 'undefined' ? noop :
  32. function( message ) {
  33. console.error( message );
  34. };
  35. // -------------------------- measurements -------------------------- //
  36. var measurements = [
  37. 'paddingLeft',
  38. 'paddingRight',
  39. 'paddingTop',
  40. 'paddingBottom',
  41. 'marginLeft',
  42. 'marginRight',
  43. 'marginTop',
  44. 'marginBottom',
  45. 'borderLeftWidth',
  46. 'borderRightWidth',
  47. 'borderTopWidth',
  48. 'borderBottomWidth'
  49. ];
  50. var measurementsLength = measurements.length;
  51. function getZeroSize() {
  52. var size = {
  53. width: 0,
  54. height: 0,
  55. innerWidth: 0,
  56. innerHeight: 0,
  57. outerWidth: 0,
  58. outerHeight: 0
  59. };
  60. for ( var i=0; i < measurementsLength; i++ ) {
  61. var measurement = measurements[i];
  62. size[ measurement ] = 0;
  63. }
  64. return size;
  65. }
  66. // -------------------------- getStyle -------------------------- //
  67. /**
  68. * getStyle, get style of element, check for Firefox bug
  69. * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
  70. */
  71. function getStyle( elem ) {
  72. var style = getComputedStyle( elem );
  73. if ( !style ) {
  74. logError( 'Style returned ' + style +
  75. '. Are you running this code in a hidden iframe on Firefox? ' +
  76. 'See https://bit.ly/getsizebug1' );
  77. }
  78. return style;
  79. }
  80. // -------------------------- setup -------------------------- //
  81. var isSetup = false;
  82. var isBoxSizeOuter;
  83. /**
  84. * setup
  85. * check isBoxSizerOuter
  86. * do on first getSize() rather than on page load for Firefox bug
  87. */
  88. function setup() {
  89. // setup once
  90. if ( isSetup ) {
  91. return;
  92. }
  93. isSetup = true;
  94. // -------------------------- box sizing -------------------------- //
  95. /**
  96. * Chrome & Safari measure the outer-width on style.width on border-box elems
  97. * IE11 & Firefox<29 measures the inner-width
  98. */
  99. var div = document.createElement('div');
  100. div.style.width = '200px';
  101. div.style.padding = '1px 2px 3px 4px';
  102. div.style.borderStyle = 'solid';
  103. div.style.borderWidth = '1px 2px 3px 4px';
  104. div.style.boxSizing = 'border-box';
  105. var body = document.body || document.documentElement;
  106. body.appendChild( div );
  107. var style = getStyle( div );
  108. // round value for browser zoom. desandro/masonry#928
  109. isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
  110. getSize.isBoxSizeOuter = isBoxSizeOuter;
  111. body.removeChild( div );
  112. }
  113. // -------------------------- getSize -------------------------- //
  114. function getSize( elem ) {
  115. setup();
  116. // use querySeletor if elem is string
  117. if ( typeof elem == 'string' ) {
  118. elem = document.querySelector( elem );
  119. }
  120. // do not proceed on non-objects
  121. if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
  122. return;
  123. }
  124. var style = getStyle( elem );
  125. // if hidden, everything is 0
  126. if ( style.display == 'none' ) {
  127. return getZeroSize();
  128. }
  129. var size = {};
  130. size.width = elem.offsetWidth;
  131. size.height = elem.offsetHeight;
  132. var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
  133. // get all measurements
  134. for ( var i=0; i < measurementsLength; i++ ) {
  135. var measurement = measurements[i];
  136. var value = style[ measurement ];
  137. var num = parseFloat( value );
  138. // any 'auto', 'medium' value will be 0
  139. size[ measurement ] = !isNaN( num ) ? num : 0;
  140. }
  141. var paddingWidth = size.paddingLeft + size.paddingRight;
  142. var paddingHeight = size.paddingTop + size.paddingBottom;
  143. var marginWidth = size.marginLeft + size.marginRight;
  144. var marginHeight = size.marginTop + size.marginBottom;
  145. var borderWidth = size.borderLeftWidth + size.borderRightWidth;
  146. var borderHeight = size.borderTopWidth + size.borderBottomWidth;
  147. var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
  148. // overwrite width and height if we can get it from style
  149. var styleWidth = getStyleSize( style.width );
  150. if ( styleWidth !== false ) {
  151. size.width = styleWidth +
  152. // add padding and border unless it's already including it
  153. ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
  154. }
  155. var styleHeight = getStyleSize( style.height );
  156. if ( styleHeight !== false ) {
  157. size.height = styleHeight +
  158. // add padding and border unless it's already including it
  159. ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
  160. }
  161. size.innerWidth = size.width - ( paddingWidth + borderWidth );
  162. size.innerHeight = size.height - ( paddingHeight + borderHeight );
  163. size.outerWidth = size.width + marginWidth;
  164. size.outerHeight = size.height + marginHeight;
  165. return size;
  166. }
  167. return getSize;
  168. });