您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自定义数值输入框元素
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/432807/1160998/InputNumber.js
- /**
- * @file 自定义数值输入框元素 InputNumber
- * @version 1.1.1.20230313
- * @author Laster2800
- * @see {@link https://gitee.com/liangjiancang/userscript/tree/master/lib/CustomElements/InputNumber InputNumber}
- */
- if (!customElements.get('laster2800-input-number')) {
- customElements.define('laster2800-input-number', class InputNumber extends HTMLInputElement {
- #arrowTid = false
- static get observedAttributes() {
- return ['type', 'step']
- }
- constructor() {
- super()
- this.#update()
- this.addEventListener('input', this.#onInput)
- this.addEventListener('blur', this.#onInputDone)
- this.addEventListener('keydown', this.#onArrowDown)
- this.addEventListener('keyup', this.#onArrowUp)
- }
- #onInput() {
- let val = this.value
- const regex = this.min < 0 ? /-?\d+(\.(\d+)?)?|-/ : /\d+(\.(\d+)?)?/
- val = regex.exec(val)?.[0] ?? ''
- if (val) {
- if (val !== '-') {
- // input listener 只应处理外极值
- if (val.startsWith('-')) {
- if (val < this.min) {
- val = String(this.min)
- }
- } else {
- if (val > this.max) {
- val = String(this.max)
- }
- }
- if (this.digits !== Number.POSITIVE_INFINITY) { // Number#toFixed() 不便于动态精度
- if (this.digits > 0) {
- const m = new RegExp(String.raw`(.+\.\d{${this.digits}}).+`).exec(val)
- if (m) {
- val = m[1]
- }
- } else {
- const idx = val.indexOf('.')
- if (idx >= 0) {
- val = val.slice(0, idx)
- }
- }
- }
- }
- this.value = val
- } else {
- this.value = ''
- }
- }
- #onInputDone() {
- let val = this.value
- if (val === '') {
- val = this.defaultValue
- }
- val = Number.parseFloat(val)
- if (!Number.isNaN(val)) {
- if (val === 0) {
- if (this.allowZero === 'true') {
- this.value = '0'
- return
- } else if (this.allowZero === 'false') {
- val = Number.parseFloat(this.defaultValue)
- if (val === 0) {
- this.value = '0'
- } else {
- this.value = ''
- this.#onInputDone()
- }
- return
- }
- }
- if (val > this.max) {
- val = this.max
- } else if (val < this.min) {
- val = this.min
- }
- if (this.digits !== Number.POSITIVE_INFINITY) {
- val = String(val)
- if (this.digits > 0) {
- const m = new RegExp(String.raw`(.+\.\d{${this.digits}}).+`).exec(val)
- if (m) {
- val = m[1]
- }
- } else {
- const idx = val.indexOf('.')
- if (idx >= 0) {
- val = val.slice(0, idx)
- }
- }
- }
- this.value = val
- }
- }
- /** @param {KeyboardEvent} e */
- #onArrowDown(e) {
- let move = ({ ArrowUp: 1, ArrowDown: -1 })[e.key]
- if (move) {
- e.preventDefault()
- if (this.#arrowTid) return
- this.#arrowTid = setTimeout(() => { this.#arrowTid = null }, 100)
- if (e.altKey) {
- move *= 0.1
- } else if (e.shiftKey) {
- move *= 10
- } else if (e.ctrlKey) {
- move *= 100
- }
- let val = this.value
- if (val === '') {
- val = this.defaultValue
- }
- val = Number.parseFloat(val)
- if (Number.isNaN(val)) return
- val += move
- if (val > this.max) {
- val = this.max
- } else if (val < this.min) {
- val = this.min
- }
- this.value = this.digits === Number.POSITIVE_INFINITY ? val : val.toFixed(this.digits)
- this.dispatchEvent(new Event('change'))
- }
- }
- /** @param {KeyboardEvent} e */
- #onArrowUp(e) {
- if (['ArrowUp', 'ArrowDown'].includes(e.key) && this.#arrowTid) {
- clearTimeout(this.#arrowTid)
- this.#arrowTid = null
- }
- }
- set digits(val) {
- this.setAttribute('digits', val)
- }
- get digits() {
- return this.#getNumberAttr('digits', 0, 0)
- }
- set max(val) {
- this.setAttribute('max', val)
- }
- get max() {
- return this.#getNumberAttr('max', Number.POSITIVE_INFINITY)
- }
- set min(val) {
- this.setAttribute('min', val)
- }
- get min() {
- return this.#getNumberAttr('min', 0)
- }
- set allowZero(val) {
- this.setAttribute('allow-zero', val)
- }
- get allowZero() {
- return this.getAttribute('allow-zero')
- }
- attributeChangedCallback(name, oldValue, newValue) {
- newValue && this.removeAttribute(name)
- }
- /**
- * 内部更新
- */
- #update() {
- if (this.getAttribute('type')) {
- this.removeAttribute('type')
- }
- }
- /**
- * 获取数值属性值
- * @param {string} name 属性名
- * @param {number | string} [defaultVal=0] 默认值
- * @param {number} [digits=Number.POSITIVE_INFINITY] 保留到小数点后几位
- * @returns {number} 数值属性值
- */
- #getNumberAttr(name, defaultVal = 0, digits = Number.POSITIVE_INFINITY) {
- let val = this.getAttribute(name)
- if (val == null) return defaultVal
- val = Number.parseFloat(val)
- if (Number.isNaN(val)) return defaultVal
- if (digits === 0) {
- val = Math.round(val)
- } else if (digits !== Number.POSITIVE_INFINITY) {
- val = Number.parseFloat(val.toFixed(digits))
- }
- return val
- }
- }, { extends: 'input' })
- }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址