⏹html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<hr>
半角数字<input type="text" data-validate="number">
<hr>
半角邮箱<input type="text" data-validate="email">
<hr>
带分号的时间<input type="text" data-validate="time">
</body>
<script src="../jquery.min.js"></script>
<script type="module" src="./js/17-main.js"></script>
</html>
⏹主方法
import typeHandleMap from './17-utils.js'
$(function() {
// 给所有含data-validate的文本输入框绑定焦点失去事件
for(const element of Array.from($('input:text')).values()) {
// 当文本输入框没有 data-validate 属性的时候
const validatetype = element.dataset?.validate;
if(!validatetype) {
return;
}
$(element).on('blur', ({target}) => {
// 获取校验转换的类型
const validatetypeList = target.dataset?.validate.split(',');
for(const validatetype of validatetypeList.values()) {
// 根据要校验的类型执行对应的方法,将转换之后文本放回文本框中
const invokeMethod = typeHandleMap.get(validatetype);
target.value = invokeMethod.call(this, target.value);
}
});
}
});
⏹封装的工具类
class textHandleUtils {
// 全角和半角假名的对应关系
zen2HanKanaMap = {
'ガ': 'ガ', 'ギ': 'ギ', 'グ': 'グ', 'ゲ': 'ゲ', 'ゴ': 'ゴ',
'ザ': 'ザ', 'ジ': 'ジ', 'ズ': 'ズ', 'ゼ': 'ゼ', 'ゾ': 'ゾ',
'ダ': 'ダ', 'ヂ': 'ヂ', 'ヅ': 'ヅ', 'デ': 'デ', 'ド': 'ド',
'バ': 'バ', 'ビ': 'ビ', 'ブ': 'ブ', 'ベ': 'ベ', 'ボ': 'ボ',
'パ': 'パ', 'ピ': 'ピ', 'プ': 'プ', 'ペ': 'ペ', 'ポ': 'ポ',
'ヴ': 'ヴ', 'ヷ': 'ヷ', 'ヺ': 'ヺ',
'ア': 'ア', 'イ': 'イ', 'ウ': 'ウ', 'エ': 'エ', 'オ': 'オ',
'カ': 'カ', 'キ': 'キ', 'ク': 'ク', 'ケ': 'ケ', 'コ': 'コ',
'サ': 'サ', 'シ': 'シ', 'ス': 'ス', 'セ': 'セ', 'ソ': 'ソ',
'タ': 'タ', 'チ': 'チ', 'ツ': 'ツ', 'テ': 'テ', 'ト': 'ト',
'ナ': 'ナ', 'ニ': 'ニ', 'ヌ': 'ヌ', 'ネ': 'ネ', 'ノ': 'ノ',
'ハ': 'ハ', 'ヒ': 'ヒ', 'フ': 'フ', 'ヘ': 'ヘ', 'ホ': 'ホ',
'マ': 'マ', 'ミ': 'ミ', 'ム': 'ム', 'メ': 'メ', 'モ': 'モ',
'ヤ': 'ヤ', 'ユ': 'ユ', 'ヨ': 'ヨ',
'ラ': 'ラ', 'リ': 'リ', 'ル': 'ル', 'レ': 'レ', 'ロ': 'ロ',
'ワ': 'ワ', 'ヲ': 'ヲ', 'ン': 'ン',
'ァ': 'ァ', 'ィ': 'ィ', 'ゥ': 'ゥ', 'ェ': 'ェ', 'ォ': 'ォ',
'ッ': 'ッ', 'ャ': 'ャ', 'ュ': 'ュ', 'ョ': 'ョ',
'。': '。', '、': '、', 'ー': 'ー', '「': '「', '」': '」', '・': '・'
};
// 半角和全角假名的对应关系
han2ZenKanaMap = {
'ガ': 'ガ', 'ギ': 'ギ', 'グ': 'グ', 'ゲ': 'ゲ', 'ゴ': 'ゴ',
'ザ': 'ザ', 'ジ': 'ジ', 'ズ': 'ズ', 'ゼ': 'ゼ', 'ゾ': 'ゾ',
'ダ': 'ダ', 'ヂ': 'ヂ', 'ヅ': 'ヅ', 'デ': 'デ', 'ド': 'ド',
'バ': 'バ', 'ビ': 'ビ', 'ブ': 'ブ', 'ベ': 'ベ', 'ボ': 'ボ',
'パ': 'パ', 'ピ': 'ピ', 'プ': 'プ', 'ペ': 'ペ', 'ポ': 'ポ',
'ヴ': 'ヴ', 'ヷ': 'ヷ', 'ヺ': 'ヺ',
'ア': 'ア', 'イ': 'イ', 'ウ': 'ウ', 'エ': 'エ', 'オ': 'オ',
'カ': 'カ', 'キ': 'キ', 'ク': 'ク', 'ケ': 'ケ', 'コ': 'コ',
'サ': 'サ', 'シ': 'シ', 'ス': 'ス', 'セ': 'セ', 'ソ': 'ソ',
'タ': 'タ', 'チ': 'チ', 'ツ': 'ツ', 'テ': 'テ', 'ト': 'ト',
'ナ': 'ナ', 'ニ': 'ニ', 'ヌ': 'ヌ', 'ネ': 'ネ', 'ノ': 'ノ',
'ハ': 'ハ', 'ヒ': 'ヒ', 'フ': 'フ', 'ヘ': 'ヘ', 'ホ': 'ホ',
'マ': 'マ', 'ミ': 'ミ', 'ム': 'ム', 'メ': 'メ', 'モ': 'モ',
'ヤ': 'ヤ', 'ユ': 'ユ', 'ヨ': 'ヨ',
'ラ': 'ラ', 'リ': 'リ', 'ル': 'ル', 'レ': 'レ', 'ロ': 'ロ',
'ワ': 'ワ', 'ヲ': 'ヲ', 'ン': 'ン',
'ァ': 'ァ', 'ィ': 'ィ', 'ゥ': 'ゥ', 'ェ': 'ェ', 'ォ': 'ォ',
'ッ': 'ッ', 'ャ': 'ャ', 'ュ': 'ュ', 'ョ': 'ョ',
'。': '。', '、': '、', 'ー': 'ー', '「': '「', '」': '」', '・': '・', '-': 'ー',
};
constructor() {}
// 半角转换全角(英数符号)
han2ZenAlphaNumberSymbol(value) {
return value.replace(/[!-~]/g, function (s) {
return String.fromCharCode(s.charCodeAt(0) + 0xFEE0);
});
}
// 全角转换半角(英数符号)
zen2HanAlphaNumberSymbol(value) {
let s = value.replace(/[!-~]/g, function (s) {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
return s.replace(/[‐-―ー]/g, '-');
}
// 全角假名转换半角假名
zen2HanKana(value) {
const reg = new RegExp('(' + Object.keys(this.zen2HanKanaMap).join('|') + ')', 'g');
return value.replace(reg, function (match) { return kanaMap[match]; }).replace(/゛/g, '゙').replace(/゜/g, '゚');
}
// 半角假名转换全角假名
han2ZenKana(value) {
const reg = new RegExp('(' + Object.keys(this.han2ZenKanaMap).join('|') + ')', 'g');
return value.replace(reg, function (match) { return kanaMap[match]; }).replace(/゙/g, '゛').replace(/゚/g, '゜');
}
// 删除数字和 - 之外
removeNonHyphenNumber(value) {
return value.replace(/[^\d-]/g, '');
}
// 删除数字和 : 之外
removeNonColonNumber(value) {
return value.replace(/[^\d:]/g, '');
}
// 删除数字之外
removeNonNumber(value) {
return value.replace(/[^\d]/g, '');
}
}
const textHandleClass = new textHandleUtils();
// 类型对应的处理方法
const typeHandleMap = new Map([
// 全角
['zenkaku', (value) => {
const value1 = textHandleClass.han2ZenKana(value);
return textHandleClass.han2ZenAlphaNumberSymbol(value1);
}],
// 半角
['hankaku', (value) => {
const value1 = textHandleClass.zen2HanKana(value);
return textHandleClass.zen2HanAlphaNumberSymbol(value1);
}],
// 邮箱
['email', (value) => {
return textHandleClass.zen2HanAlphaNumberSymbol(value);
}],
// 电话
['tel', (value) => {
const value1 = textHandleClass.zen2HanAlphaNumberSymbol(value);
return textHandleClass.removeNonHyphenNumber(value1);
}],
// 邮编
['postCode', (value) => {
const value1 = textHandleClass.zen2HanAlphaNumberSymbol(value);
return textHandleClass.removeNonHyphenNumber(value1);
}],
// 用户名
['userName', (value) => {
const value1 = textHandleClass.zen2HanAlphaNumberSymbol(value);
return textHandleClass.han2ZenKana(value1);
}],
// 时间
['time', (value) => {
const value1 = textHandleClass.zen2HanAlphaNumberSymbol(value);
return textHandleClass.removeNonColonNumber(value1);
}],
// 数字
['number', (value) => {
const value1 = textHandleClass.zen2HanAlphaNumberSymbol(value);
return textHandleClass.removeNonNumber(value1);
}]
]);
export default typeHandleMap;
效果
🔍失去焦点前
🔍失去焦点后