您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

jquery.autosize.js 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*!
  2. Autosize v1.18.1 - 2013-11-05
  3. Automatically adjust textarea height based on user input.
  4. (c) 2013 Jack Moore - http://www.jacklmoore.com/autosize
  5. license: http://www.opensource.org/licenses/mit-license.php
  6. */
  7. (function ($) {
  8. var
  9. defaults = {
  10. className: 'autosizejs',
  11. append: '',
  12. callback: false,
  13. resizeDelay: 10
  14. },
  15. // border:0 is unnecessary, but avoids a bug in Firefox on OSX
  16. copy = '<textarea tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;"/>',
  17. // line-height is conditionally included because IE7/IE8/old Opera do not return the correct value.
  18. typographyStyles = [
  19. 'fontFamily',
  20. 'fontSize',
  21. 'fontWeight',
  22. 'fontStyle',
  23. 'letterSpacing',
  24. 'textTransform',
  25. 'wordSpacing',
  26. 'textIndent'
  27. ],
  28. // to keep track which textarea is being mirrored when adjust() is called.
  29. mirrored,
  30. // the mirror element, which is used to calculate what size the mirrored element should be.
  31. mirror = $(copy).data('autosize', true)[0];
  32. // test that line-height can be accurately copied.
  33. mirror.style.lineHeight = '99px';
  34. if ($(mirror).css('lineHeight') === '99px') {
  35. typographyStyles.push('lineHeight');
  36. }
  37. mirror.style.lineHeight = '';
  38. $.fn.autosize = function (options) {
  39. if (!this.length) {
  40. return this;
  41. }
  42. options = $.extend({}, defaults, options || {});
  43. if (mirror.parentNode !== document.body) {
  44. $(document.body).append(mirror);
  45. }
  46. return this.each(function () {
  47. var
  48. ta = this,
  49. $ta = $(ta),
  50. maxHeight,
  51. minHeight,
  52. boxOffset = 0,
  53. callback = $.isFunction(options.callback),
  54. originalStyles = {
  55. height: ta.style.height,
  56. overflow: ta.style.overflow,
  57. overflowY: ta.style.overflowY,
  58. wordWrap: ta.style.wordWrap,
  59. resize: ta.style.resize
  60. },
  61. timeout,
  62. width = $ta.width();
  63. if ($ta.data('autosize')) {
  64. // exit if autosize has already been applied, or if the textarea is the mirror element.
  65. return;
  66. }
  67. $ta.data('autosize', true);
  68. if ($ta.css('box-sizing') === 'border-box' || $ta.css('-moz-box-sizing') === 'border-box' || $ta.css('-webkit-box-sizing') === 'border-box'){
  69. boxOffset = $ta.outerHeight() - $ta.height();
  70. }
  71. // IE8 and lower return 'auto', which parses to NaN, if no min-height is set.
  72. minHeight = Math.max(parseInt($ta.css('minHeight'), 10) - boxOffset || 0, $ta.height());
  73. $ta.css({
  74. overflow: 'hidden',
  75. overflowY: 'hidden',
  76. wordWrap: 'break-word', // horizontal overflow is hidden, so break-word is necessary for handling words longer than the textarea width
  77. resize: ($ta.css('resize') === 'none' || $ta.css('resize') === 'vertical') ? 'none' : 'horizontal'
  78. });
  79. // The mirror width must exactly match the textarea width, so using getBoundingClientRect because it doesn't round the sub-pixel value.
  80. function setWidth() {
  81. var style, width;
  82. if ('getComputedStyle' in window) {
  83. style = window.getComputedStyle(ta, null);
  84. width = ta.getBoundingClientRect().width;
  85. $.each(['paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'], function(i,val){
  86. width -= parseInt(style[val],10);
  87. });
  88. mirror.style.width = width + 'px';
  89. }
  90. else {
  91. // window.getComputedStyle, getBoundingClientRect returning a width are unsupported and unneeded in IE8 and lower.
  92. mirror.style.width = Math.max($ta.width(), 0) + 'px';
  93. }
  94. }
  95. function initMirror() {
  96. var styles = {};
  97. mirrored = ta;
  98. mirror.className = options.className;
  99. maxHeight = parseInt($ta.css('maxHeight'), 10);
  100. // mirror is a duplicate textarea located off-screen that
  101. // is automatically updated to contain the same text as the
  102. // original textarea. mirror always has a height of 0.
  103. // This gives a cross-browser supported way getting the actual
  104. // height of the text, through the scrollTop property.
  105. $.each(typographyStyles, function(i,val){
  106. styles[val] = $ta.css(val);
  107. });
  108. $(mirror).css(styles);
  109. setWidth();
  110. // Chrome-specific fix:
  111. // When the textarea y-overflow is hidden, Chrome doesn't reflow the text to account for the space
  112. // made available by removing the scrollbar. This workaround triggers the reflow for Chrome.
  113. if (window.chrome) {
  114. var width = ta.style.width;
  115. ta.style.width = '0px';
  116. var ignore = ta.offsetWidth;
  117. ta.style.width = width;
  118. }
  119. }
  120. // Using mainly bare JS in this function because it is going
  121. // to fire very often while typing, and needs to very efficient.
  122. function adjust() {
  123. var height, original;
  124. if (mirrored !== ta) {
  125. initMirror();
  126. } else {
  127. setWidth();
  128. }
  129. mirror.value = ta.value + options.append;
  130. mirror.style.overflowY = ta.style.overflowY;
  131. original = parseInt(ta.style.height,10);
  132. // Setting scrollTop to zero is needed in IE8 and lower for the next step to be accurately applied
  133. mirror.scrollTop = 0;
  134. mirror.scrollTop = 9e4;
  135. // Using scrollTop rather than scrollHeight because scrollHeight is non-standard and includes padding.
  136. height = mirror.scrollTop;
  137. if (maxHeight && height > maxHeight) {
  138. ta.style.overflowY = 'scroll';
  139. height = maxHeight;
  140. } else {
  141. ta.style.overflowY = 'hidden';
  142. if (height < minHeight) {
  143. height = minHeight;
  144. }
  145. }
  146. height += boxOffset;
  147. if (original !== height) {
  148. ta.style.height = height + 'px';
  149. if (callback) {
  150. options.callback.call(ta,ta);
  151. }
  152. }
  153. }
  154. function resize () {
  155. clearTimeout(timeout);
  156. timeout = setTimeout(function(){
  157. var newWidth = $ta.width();
  158. if (newWidth !== width) {
  159. width = newWidth;
  160. adjust();
  161. }
  162. }, parseInt(options.resizeDelay,10));
  163. }
  164. if ('onpropertychange' in ta) {
  165. if ('oninput' in ta) {
  166. // Detects IE9. IE9 does not fire onpropertychange or oninput for deletions,
  167. // so binding to onkeyup to catch most of those occasions. There is no way that I
  168. // know of to detect something like 'cut' in IE9.
  169. $ta.on('input.autosize keyup.autosize', adjust);
  170. } else {
  171. // IE7 / IE8
  172. $ta.on('propertychange.autosize', function(){
  173. if(event.propertyName === 'value'){
  174. adjust();
  175. }
  176. });
  177. }
  178. } else {
  179. // Modern Browsers
  180. $ta.on('input.autosize', adjust);
  181. }
  182. // Set options.resizeDelay to false if using fixed-width textarea elements.
  183. // Uses a timeout and width check to reduce the amount of times adjust needs to be called after window resize.
  184. if (options.resizeDelay !== false) {
  185. $(window).on('resize.autosize', resize);
  186. }
  187. // Event for manual triggering if needed.
  188. // Should only be needed when the value of the textarea is changed through JavaScript rather than user input.
  189. $ta.on('autosize.resize', adjust);
  190. // Event for manual triggering that also forces the styles to update as well.
  191. // Should only be needed if one of typography styles of the textarea change, and the textarea is already the target of the adjust method.
  192. $ta.on('autosize.resizeIncludeStyle', function() {
  193. mirrored = null;
  194. adjust();
  195. });
  196. $ta.on('autosize.destroy', function(){
  197. mirrored = null;
  198. clearTimeout(timeout);
  199. $(window).off('resize', resize);
  200. $ta
  201. .off('autosize')
  202. .off('.autosize')
  203. .css(originalStyles)
  204. .removeData('autosize');
  205. });
  206. // Call adjust in case the textarea already contains text.
  207. adjust();
  208. });
  209. };
  210. }(window.jQuery || window.$)); // jQuery or jQuery-like library, such as Zepto