jquery.placeholder.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*! http://mths.be/placeholder v2.0.8 by @mathias */
  2. ;(function(window, document, $) {
  3. // Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so
  4. var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]';
  5. var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini;
  6. var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini;
  7. var prototype = $.fn;
  8. var valHooks = $.valHooks;
  9. var propHooks = $.propHooks;
  10. var hooks;
  11. var placeholder;
  12. if (isInputSupported && isTextareaSupported) {
  13. placeholder = prototype.placeholder = function() {
  14. return this;
  15. };
  16. placeholder.input = placeholder.textarea = true;
  17. } else {
  18. placeholder = prototype.placeholder = function() {
  19. var $this = this;
  20. $this
  21. .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
  22. .not('.placeholder')
  23. .bind({
  24. 'focus.placeholder': clearPlaceholder,
  25. 'blur.placeholder': setPlaceholder
  26. })
  27. .data('placeholder-enabled', true)
  28. .trigger('blur.placeholder');
  29. return $this;
  30. };
  31. placeholder.input = isInputSupported;
  32. placeholder.textarea = isTextareaSupported;
  33. hooks = {
  34. 'get': function(element) {
  35. var $element = $(element);
  36. var $passwordInput = $element.data('placeholder-password');
  37. if ($passwordInput) {
  38. return $passwordInput[0].value;
  39. }
  40. return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
  41. },
  42. 'set': function(element, value) {
  43. var $element = $(element);
  44. var $passwordInput = $element.data('placeholder-password');
  45. if ($passwordInput) {
  46. return $passwordInput[0].value = value;
  47. }
  48. if (!$element.data('placeholder-enabled')) {
  49. return element.value = value;
  50. }
  51. if (value == '') {
  52. element.value = value;
  53. // Issue #56: Setting the placeholder causes problems if the element continues to have focus.
  54. if (element != safeActiveElement()) {
  55. // We can't use `triggerHandler` here because of dummy text/password inputs :(
  56. setPlaceholder.call(element);
  57. }
  58. } else if ($element.hasClass('placeholder')) {
  59. clearPlaceholder.call(element, true, value) || (element.value = value);
  60. } else {
  61. element.value = value;
  62. }
  63. // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
  64. return $element;
  65. }
  66. };
  67. if (!isInputSupported) {
  68. valHooks.input = hooks;
  69. propHooks.value = hooks;
  70. }
  71. if (!isTextareaSupported) {
  72. valHooks.textarea = hooks;
  73. propHooks.value = hooks;
  74. }
  75. $(function() {
  76. // Look for forms
  77. $(document).delegate('form', 'submit.placeholder', function() {
  78. // Clear the placeholder values so they don't get submitted
  79. var $inputs = $('.placeholder', this).each(clearPlaceholder);
  80. setTimeout(function() {
  81. $inputs.each(setPlaceholder);
  82. }, 10);
  83. });
  84. });
  85. // Clear placeholder values upon page reload
  86. $(window).bind('beforeunload.placeholder', function() {
  87. $('.placeholder').each(function() {
  88. this.value = '';
  89. });
  90. });
  91. }
  92. function args(elem) {
  93. // Return an object of element attributes
  94. var newAttrs = {};
  95. var rinlinejQuery = /^jQuery\d+$/;
  96. $.each(elem.attributes, function(i, attr) {
  97. if (attr.specified && !rinlinejQuery.test(attr.name)) {
  98. newAttrs[attr.name] = attr.value;
  99. }
  100. });
  101. return newAttrs;
  102. }
  103. function clearPlaceholder(event, value) {
  104. var input = this;
  105. var $input = $(input);
  106. if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
  107. if ($input.data('placeholder-password')) {
  108. $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
  109. // If `clearPlaceholder` was called from `$.valHooks.input.set`
  110. if (event === true) {
  111. return $input[0].value = value;
  112. }
  113. $input.focus();
  114. } else {
  115. input.value = '';
  116. $input.removeClass('placeholder');
  117. input == safeActiveElement() && input.select();
  118. }
  119. }
  120. }
  121. function setPlaceholder() {
  122. var $replacement;
  123. var input = this;
  124. var $input = $(input);
  125. var id = this.id;
  126. if (input.value == '') {
  127. if (input.type == 'password') {
  128. if (!$input.data('placeholder-textinput')) {
  129. try {
  130. $replacement = $input.clone().attr({ 'type': 'text' });
  131. } catch(e) {
  132. $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
  133. }
  134. $replacement
  135. .removeAttr('name')
  136. .data({
  137. 'placeholder-password': $input,
  138. 'placeholder-id': id
  139. })
  140. .bind('focus.placeholder', clearPlaceholder);
  141. $input
  142. .data({
  143. 'placeholder-textinput': $replacement,
  144. 'placeholder-id': id
  145. })
  146. .before($replacement);
  147. }
  148. $input = $input.removeAttr('id').hide().prev().attr('id', id).show();
  149. // Note: `$input[0] != input` now!
  150. }
  151. $input.addClass('placeholder');
  152. $input[0].value = $input.attr('placeholder');
  153. } else {
  154. $input.removeClass('placeholder');
  155. }
  156. }
  157. function safeActiveElement() {
  158. // Avoid IE9 `document.activeElement` of death
  159. // https://github.com/mathiasbynens/jquery-placeholder/pull/99
  160. try {
  161. return document.activeElement;
  162. } catch (exception) {}
  163. }
  164. }(this, document, jQuery));