前言:
前端现在很多时候,由于要限制文本的输入格式(这里指只允许输入数字),常常需要使用到自定义键盘。自定义键盘难免涉及到复用,资源占用等问题,有时候还会由于封装不好导致事件混乱、或者由于动画效果没实现好导致看上去很尴尬。。。等这个那个的。本人根据这些情况,小做了一个原生的数字版键盘,希望可以给大家一点灵感,代码不好之处,敬请谅解!!!
正文:
正文,也叫代码解析,是程序员学习最快最有效的方式。。。。。
keyBoard.js(封装的方法就在这里了,纯原生,不依赖,当然,IE9+哈,建议只扩展,不修改。当然,我写的不好的地方随便改,改了留个言帮我纠正一下。android后退键关闭的话,这里是没写的,需要cordova之类的插件支持才行)
1 (function(window, storage, undefined) {2 'use strict'
3
4 window.keyBoard = function() {5 varkeyBoardDiv, keyBoard, commit, dialog, input, label, span, table, tbody, tr, td;6 varkeyBoardClick, keyBoardDivClick, keyBoardTranstionEnd;7 var body = document.getElementsByTagName("body")[0];8 var keyModels ={9 SIMPLE: {10 COLS: 3,11 WIDTH: '33.3%',12 TYPE: 1,13 KEYS: [7, 8, 9, 4, 5, 6, 1, 2, 3, '-', 0, '
23 vartranstion;24 varcurrModel;25 varcloseCB;26 var inputText = "",27 currText, fixed = 0,28 offset = -1;29 var popEvent = function() {30 this.closeKeyBoard(true);31 };32 var statusUtils = function() {33 var changing = false;34 return{35 setChanging: function(status) {36 changing =status;37 },38 getChanging: function() {39 returnchanging;40 }41 }42 }();43
44 return{45 openKeyBoard: openKeyBoard,46 closeKeyBoard: closeKeyBoard,47 keyModels: keyModels48 };49
50 functionopenKeyBoard(notice, initNumber, model, callbackEvery, callbackLast, openCallback, closeCallback) {51 if(statusUtils.getChanging()) {52 return false;53 }54 statusUtils.setChanging(true);55 var _this = this;56
57 /***** 处理返回事件 *******/
58 if(window.history &&window.history.pushState) {59 window.history.pushState(null, null, document.URL);60 window.addEventListener("popstate", popEvent.bind(_this), false);61 }62 /***** 处理返回事件结束 *******/
63
64 //参数置换
65 if(typeof model === "function") {66 closeCallback =openCallback;67 openCallback =callbackLast;68 callbackLast =callbackEvery;69 callbackEvery =model;70 model =undefined;71 }72
73 //关闭事件回调赋值
74 closeCB =closeCallback;75
76 //UI
77 model = model ||keyModels.SIMPLE;78 if(!keyBoardDiv || model !==currModel) {79 inputText = "";80 currModel =model;81
82 if(keyBoardDiv) {83 body.removeChild(keyBoardDiv);84 }85
86 //键盘上的对话框
87 dialog = document.createElement("DIV");88 label = document.createElement("DIV");89 span = document.createElement("SPAN");90 input = document.createElement("SPAN");91 commit = document.createElement("BUTTON");92
93 dialog.className = 'qs-keyBoard-dialog';94 commit.innerHTML = "完成";95 input.className = "qs-inset-input";96 input.style.textAlign = 'center';97 label.appendChild(input);98 label.appendChild(commit);99 dialog.appendChild(span);100 dialog.appendChild(label);101
102 keyBoardDiv = document.createElement("DIV");103 keyBoardDiv.className = "qs-key-board-bg";104
105 //键盘部分
106 keyBoard = document.createElement("DIV");107 table = document.createElement("TABLE");108 tbody = document.createElement("TBODY");109 keyBoard.className = "qs-key-board";110 keyBoard.id = 'qs-keyboard-id';111 table.border = '0';112 for(var i = 0; i < currModel.KEYS.length; i++) {113 if(i % currModel.COLS === 0) {114 tr = document.createElement("TR");115 }116 if(currModel.KEYS[i] || currModel.KEYS[i] === 0) {117 td = document.createElement("TD");118 td.style.width =currModel.WIDTH;119 if(typeof(currModel.KEYS[i]) === "object") {120 currModel.KEYS[i].icon ? td.className = currModel.KEYS[i].icon : td.innerHTML =currModel.KEYS[i].text;121 currModel.KEYS[i].rows && td.setAttribute('rowspan', currModel.KEYS[i].rows);122 td.setAttribute("qs-data-value", currModel.KEYS[i].text);123 } else{124 td.innerHTML =currModel.KEYS[i];125 td.setAttribute("qs-data-value", currModel.KEYS[i]);126 }127 tr.appendChild(td);128 }129 if(i % currModel.COLS === currModel.COLS - 1) {130 tbody.appendChild(tr);131 }132 }133 table.appendChild(tbody);134 keyBoard.appendChild(dialog);135 keyBoard.appendChild(table);136 keyBoardDiv.appendChild(keyBoard);137 body.appendChild(keyBoardDiv);138 }139
140 input.innerHTML = inputText = (initNumber + "") || "";141 span.innerHTML = notice || '';142
143 //预移除事件(快速点击时动画误差)
144 transtion = whichTransitionEvent(keyBoardDiv);//判断当前使用的事件类型
145 if(keyBoardClick) {146 keyBoard.removeEventListener("click", keyBoardClick);147 keyBoardDiv.removeEventListener("click", keyBoardDivClick);148 keyBoardDiv.removeEventListener(transtion, keyBoardTranstionEnd);149 }150
151 //监听事件
152 keyBoardDivClick = function() {153 inputText = inputText === '-' ? '': inputText;154 callbackLast && callbackLast(inputText ? Number(inputText) : '');155 _this.closeKeyBoard();156 };157
158 keyBoardClick = function(e) {159 switch(e.target.nodeName) {160 case 'TD':161 e.stopPropagation();162 e.preventDefault();163 doKeys(e);164 break;165 case 'BUTTON':166 break;167 default:168 e.stopPropagation();169 e.preventDefault();170 break;171 }172 };173
174 keyBoardTranstionEnd = function() {175 statusUtils.setChanging(false);176 openCallback &&openCallback();177 };178
179 functiondoKeys(e) {180 currText = e.target.getAttribute("qs-data-value");181 inputText = inputText === '0' ? '': inputText;182 switch(currText) {183 case '-':184 inputText = inputText.indexOf('-') === -1 ? '-' + inputText : inputText.slice(1);185 break;186 case '.':187 inputText = inputText ? inputText === '-' ? inputText = '-0.' : (inputText.indexOf('.') === -1 ? inputText + '.' : inputText) : '0.';188 break;189 case '
210 functioncalcNumber(str, type) {211 str = str === '-' ? "0": str;212 offset = str.indexOf('.');213 fixed = offset > -1 ? str.length - offset - 1 : 0;214 str = Math.round(Number(str) * Math.pow(10, fixed) + Math.pow(10, fixed) * Math.pow(-1, type)) / Math.pow(10, fixed);215 returnstr.toString();216 }217
218 //注册监听事件
219 keyBoard.addEventListener("click", keyBoardClick, false);220 keyBoardDiv.addEventListener("click", keyBoardDivClick, false);221 keyBoardDiv.addEventListener(transtion, keyBoardTranstionEnd, false);222
223 keyBoardDiv.className = "qs-key-board-bg";224 setTimeout(function(){225 keyBoardDiv.className = "qs-key-board-bg qs-keyboard-up";226 });227 }228
229 /**230 * 关闭键盘231 * @param doBack 是否执行一次回退(不是导航栏返回触发的需要执行一次回退)232 */
233 functioncloseKeyBoard(doBack) {234 if(statusUtils.getChanging()) {235 return false;236 }237 statusUtils.setChanging(true);238
239 //动画完成事件
240 var closeKeyBoardTranstionEnd = function() {241 keyBoardDiv.className = "qs-key-board-bg display-none";242 statusUtils.setChanging(false);243 keyBoardDiv.removeEventListener(transtion, closeKeyBoardTranstionEnd);244
245 //键盘关闭回调事件
246 closeCB &&closeCB();247 };248 keyBoardDiv.addEventListener(transtion, closeKeyBoardTranstionEnd, false);249 keyBoardDiv.className = "qs-key-board-bg";250 inputText = '';251
252 //处理回退事件
253 if(window.history &&window.history.pushState) {254 if(!doBack) {255 window.history.back();256 }257 window.removeEventListener("popstate", popEvent);258 }259 //移除监听事件
260 keyBoard.removeEventListener("click", keyBoardClick);261 keyBoardDiv.removeEventListener("click", keyBoardDivClick);262 keyBoardDiv.removeEventListener(transtion, keyBoardTranstionEnd);263 }264
265 functionwhichTransitionEvent(el) {266 var transitions ={267 'transition': 'transitionend',268 'OTransition': 'oTransitionEnd',269 'MozTransition': 'transitionend',270 'WebkitTransition': 'webkitTransitionEnd'
271 }272
273 for(var t intransitions) {274 if(el.style[t] !==undefined) {275 returntransitions[t];276 }277 }278 }279 }();280 })(window, window.localStorage)
keyboard.css (这是键盘的样式文件,随便改)
.qs-key-board-bg {
position: absolute;
pointer-events: painted;
width: 100%;
left: 0;
top: 100%;
height: 100%;
transition: top .3s ease;
-webkit-transition: top .3s ease;
z-index: 999;
-moz-user-select: none;
-ms-touch-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.qs-key-board {
background-color: white;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.qs-keyBoard-dialog {
padding: 5px 10px;
background-color: white;
box-shadow: inset 0px 5px 15px #efefef;
}
.qs-keyBoard-dialog > div {
display: flex;
height: 30px;
}
.qs-keyBoard-dialog > div > button {
width: 6em;
}
.qs-keyBoard-dialog > span {
font-size: 14px;
display: block;
padding: 2px;
color: #999999;
white-space: nowrap;
text-overflow:ellipsis;
overflow:hidden;
}
.qs-key-board > table {
width: 100%;
background-color: #efefef;
border-spacing: 6px;
border-collapse: separate;
}
.qs-key-board tr{
height: 3.5rem;
}
.qs-key-board td {
width: 33.3%;
border: solid 1px #dedede;
border-radius: 6px;
-webkit-border-radius: 6px;
font-size: 2rem;
text-align: center;
vertical-align: middle;
background-color: white;
}
.qs-key-board td:active{
background-color: #dedede;
}
.qs-keyboard-up {
top: 0%;
}
.qs-inset-input {
position: relative;
display: inline-block;
border-radius: 3px;
-webkit-border-radius: 3px;
margin-right: 10px;
border: none;
font-size: 18px !important;
width: 100%;
height: 30px !important;
line-height: 30px;
background-color: rgb(238,238,238) !important;
}
.qs-keyboard-switch {
position: absolute;
overflow: hidden;
pointer-events: painted;
right: -120px;
z-index: 1000;
margin-bottom: -7px;
transition: right 300ms ease;
-webkit-transition: right 300ms ease;
}
.qs-keyboard-switch:before{
position: absolute;
z-index: 1;
right: 25px;
top:12px;
font-size: 20px;
color: white;
line-height: 20px;
width: 20px;
height: 20px;
}
.qs-keyboard-switch-show {
right: 0px;
}
.qs-input-dialog {
width: 100%;
z-index: 999;
position: absolute;
bottom: 0;
margin-bottom: -61px;
transition: margin-bottom 300ms ease;
}
.qs-input-dialog-show {
margin-bottom: 0px;
}
index.html(调用的例子,参考用)
1
2
3
4
5
6
7
8
9
10 html, body{
11 height:100%;
12 padding:0;
13 margin:0;
14 overflow:hidden;
15 }
16
17 span#input{
18 display:inline-block;
19 border-bottom:solid 1px green;
20 width:200px;
21 height:30px;
22 line-height:30px;
23 margin:20px;
24 background-color:#EFEFEF;
25 }
26
27
28
29
30
31
32
33 functionopenKeyBoard(_this){34 keyBoard.openKeyBoard('请输入数字', _this.innerText, keyBoard.keyModels.PLUS,function(number){35 _this.innerText=number;36 });37 }38
39
40
后语:
对了,我这个键盘放在body下的,所以body应该是高度100%,宽度充满,并且又overflow:hidden的,这部分观众老爷自行调整,position改fixed也是可以的
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有