NumberInput

InputNumber组件(WebComponent

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/535838/1588053/NumberInput.js

  1. /**
  2. * @extends {HTMLElement}
  3. */
  4. class InputNumber extends HTMLElement {
  5. #minus;
  6. #input;
  7. #plus;
  8. constructor() {
  9. super();
  10. this.min = 0.1;
  11. this.max = 300;
  12. this.step = 0.1;
  13. this.value = 1;
  14.  
  15. this.#minus = document.createElement("button");
  16. this.#input = document.createElement("input");
  17. this.#plus = document.createElement("button");
  18. this.#minus.classList.add(
  19. "number-input__button",
  20. "number-input__button--minus"
  21. );
  22. this.#minus.type = "button";
  23. this.#input.classList.add("number-input__input");
  24. this.#plus.classList.add(
  25. "number-input__button",
  26. "number-input__button--plus"
  27. );
  28. this.#plus.type = "button";
  29. const shadowRoot = this.attachShadow({ mode: "open" });
  30. const style = document.createElement("style");
  31. style.textContent = `
  32. .number-input__button {
  33. width: 32px;
  34. height: 34px;
  35. background: #f5f7fa;
  36. border: none;
  37. outline: none;
  38. cursor: pointer;
  39. position: relative;
  40. transition: background 0.3s;
  41. }
  42. .number-input__button:hover {
  43. background: #e4e7ed;
  44. }
  45. .number-input__button:disabled {
  46. cursor: not-allowed;
  47. color: #c0c4cc;
  48. background: #f5f7fa;
  49. }
  50. .number-input__button::before {
  51. content: "";
  52. position: absolute;
  53. top: 50%;
  54. left: 50%;
  55. transform: translate(-50%, -50%);
  56. width: 10px;
  57. height: 2px;
  58. background: #606266;
  59. }
  60. .number-input__button--plus::after {
  61. content: "";
  62. position: absolute;
  63. top: 50%;
  64. left: 50%;
  65. transform: translate(-50%, -50%);
  66. width: 2px;
  67. height: 10px;
  68. background: #606266;
  69. }
  70. .number-input__input {
  71. width: 60px;
  72. height: 32px;
  73. border: none;
  74. border-left: 1px solid #dcdfe6;
  75. border-right: 1px solid #dcdfe6;
  76. text-align: center;
  77. outline: none;
  78. font-size: 14px;
  79. color: #606266;
  80. }
  81. :host {
  82. box-sizing: border-box;
  83. display: inline-flex;
  84. border: 1px solid #dcdfe6;
  85. border-radius: 4px;
  86. overflow: hidden;
  87. transition: all 0.25s linear;
  88. }
  89. :host(:hover) {
  90. box-shadow: 0 0 0 1px #dbe6f1;
  91. }
  92. :host(:focus-within) {
  93. box-shadow: 0 0 0 1px #409effd9;
  94. transition: all 0.25s linear;
  95. }
  96. .number-input__input:disabled {
  97. background: #f5f7fa;
  98. cursor: not-allowed;
  99. }`;
  100. shadowRoot.append(style, this.#minus, this.#input, this.#plus);
  101. }
  102. connectedCallback() {
  103. this.init();
  104. }
  105. attributeChangedCallback() {
  106. // update value
  107. }
  108. init() {
  109. this.#input.value = this.value;
  110. this.updateButtonState();
  111.  
  112. // 绑定事件
  113. this.#minus.addEventListener("click", () => this.changeValue(-this.step));
  114. this.#plus.addEventListener("click", () => this.changeValue(this.step));
  115. this.#input.addEventListener("change", () => this.validateInput());
  116. this.#input.addEventListener("keydown", (e) => this.handleKeydown(e));
  117. }
  118. changeValue(delta) {
  119. // 避免浮点运算不准确
  120. const newValue = (this.value * 10 + delta * 10) / 10;
  121. this.value = Math.max(this.min, Math.min(this.max, newValue));
  122. console.log(this.value);
  123. this.#input.value = Number.isInteger(this.value)
  124. ? this.value
  125. : this.value.toFixed(1);
  126. this.updateButtonState();
  127. }
  128. validateInput() {
  129. let value = parseFloat(this.#input.value);
  130. if (isNaN(value)) {
  131. value = this.min;
  132. }
  133. this.value = Math.max(this.min, Math.min(this.max, value));
  134. this.#input.value = Number.isInteger(this.value)
  135. ? this.value
  136. : this.value.toFixed(1);
  137. // GM_setValue("redirectInterval", this.#input.value);
  138. this.updateButtonState();
  139. }
  140. updateButtonState() {
  141. this.#minus.disabled = this.value <= this.min;
  142. this.#plus.disabled = this.value >= this.max;
  143. }
  144. handleKeydown(e) {
  145. if (e.key === "ArrowUp") {
  146. e.preventDefault();
  147. this.changeValue(this.step);
  148. } else if (e.key === "ArrowDown") {
  149. e.preventDefault();
  150. this.changeValue(-this.step);
  151. }
  152. }
  153. }
  154. customElements.define("input-number", InputNumber);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址