html的原生自定义键盘(数字版)

前言:

前端现在很多时候,由于要限制文本的输入格式(这里指只允许输入数字),常常需要使用到自定义键盘。自定义键盘难免涉及到复用,资源占用等问题,有时候还会由于封装不好导致事件混乱、或者由于动画效果没实现好导致看上去很尴尬。。。等这个那个的。本人根据这些情况,小做了一个原生的数字版键盘,希望可以给大家一点灵感,代码不好之处,敬请谅解!!!

正文:

  正文,也叫代码解析,是程序员学习最快最有效的方式。。。。。

keyBoard.js(封装的方法就在这里了,纯原生,不依赖,当然,IE9+哈,建议只扩展,不修改。当然,我写的不好的地方随便改,改了留个言帮我纠正一下。android后退键关闭的话,这里是没写的,需要cordova之类的插件支持才行)

  1 (function(window, storage, undefined) {
  2     'use strict'
  3 
  4     window.keyBoard = function() {
  5         var keyBoardDiv, keyBoard, commit, dialog, input, label, span, table, tbody, tr, td;
  6         var keyBoardClick, 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, '<']
 14             },
 15             PLUS: {
 16                 COLS: 4,
 17                 WIDTH: '25%',
 18                 TYPE: 1,
 19                 KEYS: [7, 8, 9, 'C', 4, 5, 6, '↑', 1, 2, 3, '↓', '-', 0, '.', '<']
 20             }
 21         };
 22 
 23         var transtion;
 24         var currModel;
 25         var closeCB;
 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                     return changing;
 40                 }
 41             }
 42         }();
 43 
 44         return {
 45             openKeyBoard: openKeyBoard,
 46             closeKeyBoard: closeKeyBoard,
 47             keyModels: keyModels
 48         };
 49 
 50         function openKeyBoard(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             function doKeys(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 '<':
190                         inputText = inputText ? inputText.slice(0, -1) : '';
191                         break;
192                     case 'C':
193                         inputText = '';
194                         break;
195                     case '↑':
196                         inputText = calcNumber(inputText, 2);
197                         break;
198                     case '↓':
199                         inputText = calcNumber(inputText, 1);
200                         break;
201                     default:
202                         inputText = inputText === '-0' ? '-' : inputText;
203                         inputText += currText;
204                         break;
205                 }
206                 input.innerHTML = inputText;
207                 callbackEvery && callbackEvery(inputText ? Number(inputText) : '');
208             }
209 
210             function calcNumber(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                 return str.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         function closeKeyBoard(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         function whichTransitionEvent(el) {
266             var transitions = {
267                 'transition': 'transitionend',
268                 'OTransition': 'oTransitionEnd',
269                 'MozTransition': 'transitionend',
270                 'WebkitTransition': 'webkitTransitionEnd'
271             }
272 
273             for(var t in transitions) {
274                 if(el.style[t] !== undefined) {
275                     return transitions[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 <!DOCTYPE html>
 2 <html>
 3 
 4     <head>
 5         <meta charset="UTF-8">
 6         <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
 7         <title></title>
 8         <link rel="stylesheet" href="css/keyBoard.css" />
 9         <style>
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         </style>
27     </head>
28 
29     <body>
30         <span id="input" onclick="openKeyBoard(this)"></span>
31     </body>
32     <script>
33         function openKeyBoard(_this){
34             keyBoard.openKeyBoard('请输入数字', _this.innerText, keyBoard.keyModels.PLUS, function(number){
35                 _this.innerText = number;
36             });
37         }
38     </script>
39     <script type="text/javascript" src="js/keyBoard.js" ></script>
40 </html>

后语:

  对了,我这个键盘放在body下的,所以body应该是高度100%,宽度充满,并且又overflow:hidden的,这部分观众老爷自行调整,position改fixed也是可以的

转载于:https://www.cnblogs.com/longhuangv5/p/8979603.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值