Greasy Fork 支持简体中文。

Clear Button For Almost Every Text Input Field

Adds clear button for almost every <input type="text">, like ms-clear.

目前為 2016-01-02 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Clear Button For Almost Every Text Input Field
  3. // @name:ja Clear Button For Almost Every Text Input Field
  4. // @namespace https://greasyfork.org/ja/users/24052-granony
  5. // @description Adds clear button for almost every <input type="text">, like ms-clear.
  6. // @description:ja ほぼすべての<input type="text">に対して ms-clear のようなクリアボタンを追加します.
  7. // @include http://*
  8. // @include https://*
  9. // @version 1.0.0
  10. // @grant none
  11. // @license MIT License
  12. // ==/UserScript==
  13. /*
  14. = Detailed Description (Japanese) =
  15. このスクリプトはほとんどのサイトのテキストフィールドに対してレイアウトを崩
  16. すことなしに ms-clear のようなクリアボタンを追加します.クリアボタンはテキ
  17. ストフィールドにマウスカーソルがある場合のみ,フィールド内部の右側
  18. (text-align=="right"の場合は左側)に表示されます.クリアボタンの表示される
  19. 位置にサイトが送信ボタンなどの要素を配置している場合 (たとえば Twitter の検
  20. 索フォーム) には動作しません.
  21.  
  22. = Detailed Description (English) =
  23. This script adds clear button for almost evey text-field in web site
  24. without breaking its layout, like ms-clear. The clear button is
  25. displayed on the right side (or left side if text-align=="right") of
  26. the inside of the field when the mouse cursor is over the field. The
  27. clear button does not work if the web site puts some elements (such as
  28. submit button) on the clear button's place (e.g. search form in Twitter).
  29. */
  30. (function () {
  31. 'use strict';
  32. var wmap = new WeakMap(); // text-field と button の対応
  33. var textFields = [];
  34. // ウィンドウの左上を基準とした要素の位置を得る
  35. var getOffset = function (elem) {
  36. var rect = elem.getBoundingClientRect();
  37. var positionX = rect.left;
  38. var positionY = rect.top;
  39. var scrollX = document.body.scrollLeft;
  40. var scrollY = document.body.scrollTop;
  41. return {
  42. x: positionX + scrollX,
  43. y: positionY + scrollY
  44. };
  45. }
  46. // ボタンを作成する
  47. var createButton = function (textField) {
  48. var button = document.createElement('div');
  49. button.innerHTML = '<span style="position:relative; font-family: Arial, sans-serif">x</span>';
  50. textField.parentNode.insertBefore(button, textField.nextSibling);
  51. (function () {
  52. var bs = button.style;
  53. button.addEventListener('click', function () {
  54. textField.value = '';
  55. });
  56. textField.addEventListener('mouseenter', function () {
  57. bs.display = 'inline-block';
  58. });
  59. button.addEventListener('mouseenter', function () {
  60. bs.display = 'inline-block';
  61. });
  62. textField.addEventListener('mouseleave', function () {
  63. bs.display = 'none';
  64. });
  65. button.addEventListener('mouseleave', function () {
  66. bs.display = 'none';
  67. });
  68. })();
  69. return button;
  70. }
  71. // ボタンの位置とサイズを更新する
  72. var updateButton = function (textField) {
  73. var button = wmap.get(textField);
  74. var th = textField.clientHeight;
  75. var tw = textField.clientWidth;
  76. var size = th * 0.7;
  77. var innerShift = size * 0.1;
  78. var ts = textField.style;
  79. var tsp = ts.position? ts.position.toLowerCase(): '';
  80. var innerText = button.getElementsByTagName('span') [0];
  81. innerText.style.top = - innerShift + 'px';
  82. var bs = button.style;
  83. var bsOriginalDisplay = bs.display;
  84. bs.display = 'inline-block';
  85. bs.textAlign = 'center';
  86. bs.borderRadius = '50%';
  87. bs.fontSize = size + 'px';
  88. bs.width = size + 'px';
  89. bs.height = size + 'px';
  90. bs.lineHeight = size + 'px';
  91. bs.padding = '0';
  92. bs.margin = '0';
  93. bs.cursor = 'pointer';
  94. bs.color = '#AAAAAA';
  95. bs.backgroundColor = '#DDDDDD';
  96. bs.position = (tsp == 'fixed') ? 'fixed' : 'absolute';
  97. bs.top = 0;
  98. bs.bottom = 0;
  99. bs.left = 0;
  100. bs.right = 0;
  101. bs.zIndex = ts.zIndex ? ts.zIndex : "auto";
  102. var tOffset = getOffset(textField);
  103. var bOffset = getOffset(button);
  104. bs.top = (tOffset.y - bOffset.y) + th * 0.15 + 'px';
  105. if(getComputedStyle(textField).textAlign=='right'){
  106. bs.left = (tOffset.x - bOffset.x) + size * 0.1 + 'px';
  107. }else{
  108. bs.left = (tOffset.x - bOffset.x) + tw - size * 1.1 + 'px';
  109. }
  110. if (bsOriginalDisplay != 'inline-block') {
  111. bs.display = 'none';
  112. }
  113. return button;
  114. }
  115. // ボタンの登録
  116. // onload 時と DOM の変化が検出されるたびに実行される
  117. var registerButtons = function () {
  118. var inputs = document.getElementsByTagName('input');
  119. for (var i = 0; i < inputs.length; i++) {
  120. var input = inputs[i];
  121. var iType = input.getAttribute('type')==null?"text":input.getAttribute('type').toLowerCase();
  122. console.log(input.getAttribute('id'), input.getAttribute('type'), iType);
  123. if (iType!='text' && iType!='search') {
  124. continue;
  125. }
  126. if (wmap.has(input)) {
  127. continue;
  128. }
  129. if (getComputedStyle(input).display == 'none') {
  130. continue;
  131. }
  132. textFields.push(input);
  133. var button = createButton(input);
  134. wmap.set(input, button);
  135. updateButton(input);
  136. }
  137. return;
  138. }
  139. // 全ボタンの位置とサイズを更新
  140. var updateAllButtons = function () {
  141. for (var i = 0; i < textFields.length; i++) {
  142. updateButton(textFields[i]);
  143. }
  144. }
  145. // DOM の構築時にボタンを登録
  146. registerButtons();
  147. // Load 完了時にボタンの位置を更新
  148. window.addEventListener('load', updateAllButtons);
  149.  
  150. // ウィンドウサイズが変化した場合はボタンの位置だけ更新する
  151. (function(){
  152. var resizeTimer = false;
  153. window.addEventListener('resize', function () {
  154. if (resizeTimer !== false) {
  155. clearTimeout(resizeTimer);
  156. }
  157. resizeTimer = setTimeout(function () {
  158. updateAllButtons();
  159. }, 100);
  160. });
  161. })();
  162. // DOM の変化時には追加された text-field にボタンを登録し,
  163. // 全てのボタンの位置を更新する
  164. (function(){
  165. var DOMObserverTimer = false;
  166. var DOMObserverConfig = {
  167. attributes: true,
  168. childList: true,
  169. subtree: true
  170. };
  171. var DOMObserver = new MutationObserver(function () {
  172. if (DOMObserverTimer !== 'false') {
  173. clearTimeout(DOMObserverTimer);
  174. }
  175. DOMObserverTimer = setTimeout(function () {
  176. DOMObserver.disconnect();
  177. registerButtons();
  178. updateAllButtons();
  179. DOMObserver.observe(document.body, DOMObserverConfig);
  180. }, 100);
  181. });
  182. DOMObserver.observe(document.body, DOMObserverConfig);
  183. })();
  184. }) ();