讓input maxlength區分中英文打賞

經常有需求,在限制文本框輸入長度的時候,區分中英文,如:中文(全角符號類似)占兩個字節,英文則占一個,最近審查代碼,發現項目上存在類似需求,組內同學實現了網上經常提到的方案,輸入后替換,由于監聽的是input事件,導致任何越界輸入都會出現閃爍的情況,不同于原生效果。

回憶到以前曾經用keydown結合其他事件實現了一版,晚上沒事,就嘗試重新實現了一下,由于目前項目不考慮非webkit內核瀏覽器,只在chrome下簡單測試了下,有兼容性問題歡迎評論告知

const keyCode = [37, 38, 39, 40, 91, 8, 46, 34, 12, 20]
const specialKeyCode = [65, 67, 88]


function getLength(value) {
    return value.replace(/[^ -~]/g, '00').length
}

function slice(value, maxlength) {
    if (maxlength && maxlength > -1) {
        while (getLength(value) > maxlength) {
            value = value.slice(0, value.length - 1)
        }
    }
    return value
}

function checkKeydown(e) {
    const code = e.keyCode
    return !((e.metaKey || e.ctrlKey) && specialKeyCode.includes(code)) && !keyCode.includes(code)
}

function limit(target, targetValue) {
    const value = targetValue || target.value
    const maxLength = target.maxLength
    let newValue = value
    if (maxLength > -1 && getLength(newValue) >= maxLength) {
        newValue = slice(newValue, maxLength)
    }
    if (newValue !== value) {
        target.value = newValue
        target.focus()
    }
}

function compositionEnd(e) {
    const target = e.target
    const maxLength = target.maxLength
    if (maxLength > -1 && getLength(target.value) > maxLength) {
        limit(target)
    }
}

function limitMaxLength(input) {
    input.addEventListener('keydown', e => {
        const target = e.target
        const maxLength = target.maxLength
        const value = target.value
        if (maxLength > -1 && getLength(value) >= maxLength && checkKeydown(e)) {
            e.preventDefault()
            e.stopPropagation()
        }
    })
    input.addEventListener('input', e => {
        if (!e.isComposing) {
            compositionEnd(e)
        }
    })
    input.addEventListener('compositionend', compositionEnd)
    input.addEventListener('paste', e => {
        e.preventDefault()
        e.stopPropagation()
        const target = e.target
        const insert = e.clipboardData.getData('text/plain')
        const selectionStart = target.selectionStart
        const value = target.value
        limit(target, value.slice(0, selectionStart) + insert + value.slice(selectionStart))
    })
}

limitMaxLength(document.getElementById('input'))
讓input maxlength區分中英文
文章《讓input maxlength區分中英文》二維碼
  • 微信打賞
  • 支付寶打賞

暫無評論

(必填)

(必填)

(可選)

黑龙江22选5开奖