<body>
    <input type="text" validate rule="max:12,min:3" />
    <input type="text" validate rule="max:3,isNumber" />
</body>
body {
    padding: 50px;
    background: #34495e;
}
input {
    border: solid 10px #ddd;
    height: 30px;
}
.error {
    border: solid 10px red;
}
class Validate {
	max(value, len) {
		return value.length <= len
	}

	min(value, len) {
		return value.length >= len
	}

	isNumber(value) {
		return /^\d+$/.test(value)
	}
}

// 代理
function createProxy(target) {
	return new Proxy(target, {
		get(target, key) {
			return target[key]
		},
		set(target, key, el) {
			const rule = el.getAttribute('rule')
			const validate = new Validate()

			const state = rule.split(',').every(rule => {
				const info = rule.split(':')

				return validate[info[0]](el.value, info[1])
			})

			el.classList[state ? 'remove' : 'add']('error')

			return true
		}
	})
}

const nodes = createProxy(document.querySelectorAll('[validate]'))

nodes.forEach((item, i) => {
	item.addEventListener('keyup', function() {
		nodes[i] = this
	})
})
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.