html的原生自定义键盘(数字版)
2018-06-24 02:01:21来源:未知 阅读 ()
前言:
前端现在很多时候,由于要限制文本的输入格式(这里指只允许输入数字),常常需要使用到自定义键盘。自定义键盘难免涉及到复用,资源占用等问题,有时候还会由于封装不好导致事件混乱、或者由于动画效果没实现好导致看上去很尴尬。。。等这个那个的。本人根据这些情况,小做了一个原生的数字版键盘,希望可以给大家一点灵感,代码不好之处,敬请谅解!!!
正文:
正文,也叫代码解析,是程序员学习最快最有效的方式。。。。。
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也是可以的
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 麻雀虽小五脏俱全 Dojo自定义控件应用 2020-02-20
- 详解HTML5 使用video标签实现选择摄像头功能 2020-02-07
- Extjs Label的 fieldLabel和html属性值对齐的方法 2020-01-07
- jquery模拟LCD 时钟的html文件源代码 2019-12-08
- javascript动态判断html元素并执行不同的操作 2019-11-30
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash