Repository: simbawus/DigitalKeyboard Branch: master Commit: 38e205042d88 Files: 21 Total size: 36.5 KB Directory structure: gitextract_2cny1l90/ ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README-zh_CN.md ├── README.md ├── build/ │ └── Keyboard.js ├── config/ │ └── webpack/ │ ├── webpack.base.config.js │ ├── webpack.config.js │ ├── webpack.dev.config.js │ └── webpack.prod.config.js ├── index.html ├── package.json ├── src/ │ ├── Keyboard.js │ ├── Keyboard.scss │ ├── main.js │ └── main.scss └── test/ └── Keyboard.test.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": ["env"] } ================================================ FILE: .editorconfig ================================================ # EditorConfig helps developers define and maintain consistent # coding styles between different editors and IDEs # http://editorconfig.org root = true [**] # 编码格式 charset = utf-8 # 文件结尾符 end_of_line = lf insert_final_newline = true # 去除行尾空白字符 trim_trailing_whitespace = true # space 缩进 indent_style = space indent_size = 2 [*.md] trim_trailing_whitespace = false ================================================ FILE: .eslintignore ================================================ build node_modules ================================================ FILE: .eslintrc ================================================ { "extends": "booheefe" } ================================================ FILE: .gitignore ================================================ .idea node_modules build/app.js .coveralls.yml coverage ================================================ FILE: .travis.yml ================================================ language: node_js node_js: - "9" after_success: - yarn coveralls ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 simbawu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README-zh_CN.md ================================================ [English](README.md) | 简体中文 # DigitalKeyboard 数字键盘 [![Build Status](https://travis-ci.org/simbawus/digital-keyboard.svg?branch=master)](https://travis-ci.org/simbawus/digital-keyboard) [![Coverage Status](https://coveralls.io/repos/github/simbawus/digital-keyboard/badge.svg?branch=master)](https://coveralls.io/github/simbawus/digital-keyboard?branch=master) [![npm](https://img.shields.io/npm/v/digital-keyboard.svg)](https://www.npmjs.com/package/digital-keyboard) [![npm](https://img.shields.io/npm/dt/digital-keyboard.svg)](https://www.npmjs.com/package/digital-keyboard) [![GitHub license](https://img.shields.io/github/license/simbawus/digital-keyboard.svg)](https://github.com/simbawus/digital-keyboard/blob/master/LICENSE) - 原生js开发、不依赖任何框架和库的轻量级移动端数字键盘 - 支持身份证、手机号、整数、小数多类型输入 - API简洁,非常好上手 - 开发总结:[从0开始发布一个无依赖、高质量的npm](https://github.com/simbawus/blog/issues/12) [![Example](https://i.loli.net/2018/05/16/5afc5086957b3.gif)](https://i.loli.net/2018/05/16/5afc5086957b3.gif) ## 键盘类型
       

小数

       

整数/手机号

       

身份证

## 属性 | Property | Type | Default | Description | | :------------ | :------- | :------ | :--------------------------------------- | | el | DOM | | 键盘父节点 | | className | String | | 外部传入可控制键盘样式的class | | type | String | decimal | 键盘类型:decimal小数,integer整数,phone手机号,idcard身份证 | | language | String | chinese | 语言:chinese,english | | inputValue | Function | | 键盘输入返回值 | | integerDigits | Number | | 限制整数位数 | | decimalDigits | Number | | 限制小数位数 | ## 开始上手 ### 安装 ```shell yarn add digital-keyboard --dev ``` ### 使用示例 - **原生 JavaScript** ```html 数字键盘
``` ```javascript //digitalKeyboard.js import DigitalKeyboard from 'digital-keyboard'; function inputValue(value){ console.log(value); //DigitalKeyboard return value document.querySelector('#values').innerHTML = value; } new DigitalKeyboard( { el: document.querySelector('#app'), type: 'idcard', className: 'container', inputValue: inputValue, integerDigits: 4, decimalDigits: 2 } ); ``` - **React** ```jsx import React from 'react'; import DigitalKeyboard from "digital-keyboard"; import s from './digitalKeyboard.scss; class KeyboardPage extends React.Component { constructor(){ super(); this.inputValue = this.inputValue.bind(this); this._renderKeyboard = this._renderKeyboard.bind(this); } componentDidMount(){ this._renderKeyboard(); } inputValue(value){ console.log(value); //DigitalKeyboard return value } _renderKeyboard(){ return new DigitalKeyboard ( { el: this.refs.digitalKeyboard, className: s.container, type: 'number', inputValue: this.inputValue, integerDigits: 4, decimalDigits: 2 } ); } render(){ return (
) } } export default KeyboardPage; ``` - **Vue** ```js ``` - **Angular** ```typescript // Online-demo: https://stackblitz.com/edit/angular-hkexnq import { Component, ViewChild, OnInit, ViewEncapsulation} from '@angular/core'; import DigitalKeyboard from "digital-keyboard"; @Component({ selector: 'my-app', template: `
`, styles: [` .container { color: #333; } `], encapsulation: ViewEncapsulation.None }) export class AppComponent implements OnInit{ @ViewChild('keyboard') keyboard; ngOnInit(){ this._renderDigitalKeyboard(); } _renderDigitalKeyboard(){ return new DigitalKeyboard ( { el: this.keyboard.nativeElement, className: 'container', type: 'number', inputValue: this.inputValue, integerDigits: 4, decimalDigits: 2 } ); } inputValue(value) { console.log(value); //DigitalKeyboard return value } } ``` ## 如何贡献 欢迎每个人为这个项目做出贡献。可以从查看我们[未解决的问题](https://github.com/simbawus/DigitalKeyboard/issues)、[提交新问题](https://github.com/simbawus/DigitalKeyboard/issues/new?labels=bug)或[提出新功能](https://github.com/simbawus/DigitalKeyboard/issues/new?labels=enhancement)入手,参与讨论投票您喜欢或不喜欢的问题。 ## 开源证书 [**The MIT License**](LICENSE). ================================================ FILE: README.md ================================================ English | [简体中文](README-zh_CN.md) # Digital Keyboard [![Build Status](https://travis-ci.org/simbawus/digital-keyboard.svg?branch=master)](https://travis-ci.org/simbawus/digital-keyboard) [![Coverage Status](https://coveralls.io/repos/github/simbawus/digital-keyboard/badge.svg?branch=master)](https://coveralls.io/github/simbawus/digital-keyboard?branch=master) [![npm](https://img.shields.io/npm/v/digital-keyboard.svg)](https://www.npmjs.com/package/digital-keyboard) [![npm](https://img.shields.io/npm/dt/digital-keyboard.svg)](https://www.npmjs.com/package/digital-keyboard) [![GitHub license](https://img.shields.io/github/license/simbawus/digital-keyboard.svg)](https://github.com/simbawus/digital-keyboard/blob/master/LICENSE) - Develop with native javascript, doesn't rely on any frameworks and libraries. - Support ID card, mobile number, integer, decimal, etc. - Easy API, easy use. - Development summary:[How to release a npm package](https://github.com/simbawus/blog/issues/12). [![Example](https://i.loli.net/2018/05/16/5afc5086957b3.gif)](https://i.loli.net/2018/05/16/5afc5086957b3.gif) ## Type

decimal

integer/phone

idcard

## PropTypes | Property | Type | Default | Description | | :------------ | :------- | :------ | :--------------------------------------- | | el | DOM | | parent node | | className | String | | additonal class to control keyboard's style | | type | String | decimal | decimal,integer,phone,idcard | | language | String | chinese | chinese,english | | inputValue | Function | | return keyboard value | | integerDigits | Number | | limit integer digits | | decimalDigits | Number | | limit decimal digits | ## Getting Started ### Install ```shell yarn add digital-keyboard --dev ``` ### Usage Example - **Native JavaScript** ```html Digital Keyboard
``` ```javascript //digitalKeyboard.js import DigitalKeyboard from 'digital-keyboard'; function inputValue(value){ console.log(value); //DigitalKeyboard return value document.querySelector('#values').innerHTML = value; } new DigitalKeyboard( { el: document.querySelector('#app'), className: 'container', type: 'idcard', inputValue: inputValue, integerDigits: 4, decimalDigits: 2 } ); ``` - **React** ```jsx import React from 'react'; import DigitalKeyboard from 'digital-keyboard'; import s from './digitalKeyboard.scss'; class KeyboardPage extends React.Component { constructor(){ super(); this.inputValue = this.inputValue.bind(this); this._renderKeyboard = this._renderKeyboard.bind(this); } componentDidMount(){ this._renderKeyboard(); } inputValue(value){ console.log(value); //DigitalKeyboard return value } _renderKeyboard(){ return new DigitalKeyboard ( { el: this.refs.digitalKeyboard, className: s.container, type: 'number', inputValue: this.inputValue, integerDigits: 4, decimalDigits: 2 } ); } render(){ return (
) } } export default KeyboardPage; ``` - **Vue** ```js ``` * **Angular** ```typescript // Online-demo: https://stackblitz.com/edit/angular-hkexnq import { Component, ViewChild, OnInit, ViewEncapsulation} from '@angular/core'; import DigitalKeyboard from "digital-keyboard"; @Component({ selector: 'my-app', template: `
`, styles: [` .container { color: #333; } `], encapsulation: ViewEncapsulation.None }) export class AppComponent implements OnInit{ @ViewChild('keyboard') keyboard; ngOnInit(){ this._renderDigitalKeyboard(); } _renderDigitalKeyboard(){ return new DigitalKeyboard ( { el: this.keyboard.nativeElement, className: 'container', type: 'number', inputValue: this.inputValue, integerDigits: 4, decimalDigits: 2 } ); } inputValue(value) { console.log(value); //DigitalKeyboard return value } } ``` ## How to Contribute Anyone and everyone is welcome to contribute to this project. The best way to start is by checking our [open issues](https://github.com/simbawus/digital-keyboard/issues),[submit a new issues](https://github.com/simbawus/digital-keyboard/issues/new?labels=bug) or [feature request](https://github.com/simbawus/digital-keyboard/issues/new?labels=enhancement), participate in discussions, upvote or downvote the issues you like or dislike. ## License [**The MIT License**](LICENSE). ================================================ FILE: build/Keyboard.js ================================================ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.DigitalKeyboard=t():e.DigitalKeyboard=t()}(window,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/build/",n(n.s=6)}([function(e,t){e.exports=function(e){var t="undefined"!=typeof window&&window.location;if(!t)throw new Error("fixUrls requires window.location");if(!e||"string"!=typeof e)return e;var n=t.protocol+"//"+t.host,r=n+t.pathname.replace(/\/[^\/]*$/,"/");return e.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,function(e,t){var o,a=t.trim().replace(/^"(.*)"$/,function(e,t){return t}).replace(/^'(.*)'$/,function(e,t){return t});return/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(a)?e:(o=0===a.indexOf("//")?a:0===a.indexOf("/")?n+a:r+a.replace(/^\.\//,""),"url("+JSON.stringify(o)+")")})}},function(e,t,n){var r,o,a={},i=(r=function(){return window&&document&&document.all&&!window.atob},function(){return void 0===o&&(o=r.apply(this,arguments)),o}),s=function(e){var t={};return function(e){if("function"==typeof e)return e();if(void 0===t[e]){var n=function(e){return document.querySelector(e)}.call(this,e);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}t[e]=n}return t[e]}}(),c=null,u=0,l=[],f=n(0);function d(e,t){for(var n=0;n=0&&l.splice(t,1)}function v(e){var t=document.createElement("style");return e.attrs.type="text/css",y(t,e.attrs),p(e,t),t}function y(e,t){Object.keys(t).forEach(function(n){e.setAttribute(n,t[n])})}function g(e,t){var n,r,o,a;if(t.transform&&e.css){if(!(a=t.transform(e.css)))return function(){};e.css=a}if(t.singleton){var i=u++;n=c||(c=v(t)),r=w.bind(null,n,i,!1),o=w.bind(null,n,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return e.attrs.type="text/css",e.attrs.rel="stylesheet",y(t,e.attrs),p(e,t),t}(t),r=function(e,t,n){var r=n.css,o=n.sourceMap,a=void 0===t.convertToAbsoluteUrls&&o;(t.convertToAbsoluteUrls||a)&&(r=f(r));o&&(r+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var i=new Blob([r],{type:"text/css"}),s=e.href;e.href=URL.createObjectURL(i),s&&URL.revokeObjectURL(s)}.bind(null,n,t),o=function(){b(n),n.href&&URL.revokeObjectURL(n.href)}):(n=v(t),r=function(e,t){var n=t.css,r=t.media;r&&e.setAttribute("media",r);if(e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}.bind(null,n),o=function(){b(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else o()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=i()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=h(e,t);return d(n,t),function(e){for(var r=[],o=0;o0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.value="",this.options={language:"chinese",clearName:"清空"},Object.assign(this.options,t),this.init(t)}return o(e,[{key:"handleClick",value:function(e,t){var n=this.options;switch(e){case"delete":this.value=this.value.substr(0,this.value.length-1);break;case"clear":this.value="";break;default:switch(n.type){case"phone":this.value.length<11&&(this.value+=t);break;case"idcard":this.value.length<18&&(this.value+=t);break;case"integer":n.integerDigits&&n.integerDigits<=this.value.length?this.value=this.value:this.value+=t;break;default:var r=(this.value+t).split("."),o=r[0]&&r[0].length||0,a=r[1]&&r[1].length||0,i=!n.integerDigits||n.integerDigits>=o,s=!n.decimalDigits||n.decimalDigits>=a;1===r.length&&i?this.value+=t:2===r.length&&s?this.value+=t:this.value=this.value}}n.inputValue(this.value)}},{key:"handleClearName",value:function(){var e="清空";switch(this.options.language){case"chinese":e="清空";break;case"english":e="Clear";break;default:e="清空"}this.options.clearName=e}},{key:"initKeys",value:function(e){var t=this.options.clearName,n={};switch(e){case"integer":case"phone":n={content:t,action:"clear"};break;case"idcard":n={content:"X",action:"value"};break;default:n={content:".",action:"value"}}this.items=[{content:"1",action:"value"},{content:"2",action:"value"},{content:"3",action:"value"},{content:"4",action:"value"},{content:"5",action:"value"},{content:"6",action:"value"},{content:"7",action:"value"},{content:"8",action:"value"},{content:"9",action:"value"},n,{content:"0",action:"value"},{content:"←",action:"delete"}]}},{key:"_renderKeyboard",value:function(e){var t=this,n=this.options.clearName,r="",o=this.items.map(function(e){switch(e.content){case"X":r=i.default.keyX;break;case n:r=i.default.keyClear;break;case"←":r=i.default.keyDelete;break;default:r=""}return'"}),a=document.createElement("div");a.className=i.default.keyboard+" "+this.options.className,a.innerHTML=o.join(""),a.addEventListener("touchend",function(e){var n=e.target.dataset,r=n.action,o=n.content;t.handleClick(r,o)}),e.appendChild(a)}},{key:"init",value:function(e){this.handleClearName(),this.initKeys(e.type),this._renderKeyboard(e.el)}}]),e}();t.default=s},function(e,t,n){e.exports=n(5)}])}); ================================================ FILE: config/webpack/webpack.base.config.js ================================================ const path = require('path'); const webpack = require('webpack'); module.exports = { output: { path: path.resolve(__dirname, '../../build'), filename: '[name].js', publicPath: '/build/', libraryTarget: 'umd', library: 'DigitalKeyboard' }, module: { rules: [ { test: /\.jsx?$/, loader: 'babel-loader', exclude: /(node_modules|build|coverage)/, query: { presets: ['env'] } }, { test: /\.scss$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true, localIdentName: '[name]_[local]_[hash:base64:3]' } }, { loader: 'sass-loader' }] } ] }, plugins: [ new webpack.DefinePlugin({ // 定义环境变量 'process.env': JSON.stringify(process.env.NODE_ENV) }) ] }; ================================================ FILE: config/webpack/webpack.config.js ================================================ const base = require('./webpack.base.config'); const merge = require('webpack-merge'); let config; if (process.env.NODE_ENV === 'production') { config = require('./webpack.prod.config'); } else { config = require('./webpack.dev.config'); } module.exports = merge(base, config); ================================================ FILE: config/webpack/webpack.dev.config.js ================================================ const webpack = require('webpack'); module.exports = { entry: { app: ['./src/main.js'] }, plugins: [ new webpack.HotModuleReplacementPlugin() ], devServer: { inline: true, hot: true, host: '0.0.0.0', historyApiFallback: true, port: process.env.PORT || 8101 } }; ================================================ FILE: config/webpack/webpack.prod.config.js ================================================ module.exports = { entry: { Keyboard: ['./src/Keyboard.js'] } }; ================================================ FILE: index.html ================================================ 数字键盘
清空
================================================ FILE: package.json ================================================ { "name": "digital-keyboard", "version": "1.2.2", "main": "build/Keyboard.js", "repository": "https://github.com/simbawus/digital-keyboard.git", "author": "Simbawu ", "description": "DigitalKeyboard Component", "keywords": [ "DigitalKeyboard", "Digital", "Keyboard", "key", "webpack", "simbawu" ], "license": "MIT", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.1", "chai": "^4.1.2", "coveralls": "^3.0.1", "cross-env": "^5.1.5", "css-loader": "^0.28.9", "digital-keyboard": "^1.1.0", "eslint": "^4.19.1", "eslint-config-booheefe": "^1.1.0", "istanbul": "^0.4.5", "jsdom": "^11.10.0", "mocha": "^5.1.1", "node-sass": "^4.7.2", "sass-loader": "^6.0.6", "style-loader": "^0.20.1", "webpack": "^4.8.1", "webpack-cli": "^2.1.3", "webpack-dev-server": "^3.1.4", "webpack-merge": "^4.1.2" }, "scripts": { "build": "cross-env NODE_ENV=production webpack --mode production --config ./config/webpack/webpack.config.js", "start": "yarn && cross-env NODE_ENV=development webpack-dev-server --mode development --open 'Google Chrome' --config ./config/webpack/webpack.config.js", "test": "node ./node_modules/mocha/bin/mocha --compilers js:babel-core/register ./test/Keyboard.test.js", "cover": "istanbul cover ./node_modules/mocha/bin/_mocha", "coveralls": "yarn cover --report lcovonly && cat ./coverage/lcov.info | coveralls" } } ================================================ FILE: src/Keyboard.js ================================================ import s from './Keyboard.scss'; class DigitalKeyboard { constructor(options = {}) { this.value = ''; this.options = { language: 'chinese', clearName: '清空' }; Object.assign(this.options, options); this.init(options); } handleClick(action, content) { let { options } = this; switch (action) { case 'delete': this.value = this.value.substr(0, this.value.length - 1); break; case 'clear': this.value = ''; break; default: switch (options.type) { case 'phone': if (this.value.length < 11) { this.value += content; } break; case 'idcard': if (this.value.length < 18) { this.value += content; } break; case 'integer': if (options.integerDigits && options.integerDigits <= this.value.length) { this.value = this.value; } else { this.value += content; } break; default: let _value = this.value + content; let _valueArr = _value.split('.'); let integerDigits = _valueArr[0] && _valueArr[0].length || 0; let decimalDigits = _valueArr[1] && _valueArr[1].length || 0; let integerPass = !options.integerDigits || options.integerDigits >= integerDigits; let decimalPass = !options.decimalDigits || options.decimalDigits >= decimalDigits; if (_valueArr.length === 1 && integerPass) { this.value += content; } else if (_valueArr.length === 2 && decimalPass) { this.value += content; } else { this.value = this.value; } } break; } options.inputValue(this.value); } handleClearName() { const { language } = this.options; let clearName = '清空'; switch (language) { case 'chinese': clearName = '清空'; break; case 'english': clearName = 'Clear'; break; default: clearName = '清空'; } this.options.clearName = clearName; } initKeys(type) { const { clearName } = this.options; let typeKey = {}; switch (typeKey) { } switch (type) { case 'integer': typeKey = { content: clearName, action: 'clear' }; break; case 'phone': typeKey = { content: clearName, action: 'clear' }; break; case 'idcard': typeKey = { content: 'X', action: 'value' }; break; default: typeKey = { content: '.', action: 'value' }; break; } this.items = [ { 'content': '1', 'action': 'value' }, { 'content': '2', 'action': 'value' }, { 'content': '3', 'action': 'value' }, { 'content': '4', 'action': 'value' }, { 'content': '5', 'action': 'value' }, { 'content': '6', 'action': 'value' }, { 'content': '7', 'action': 'value' }, { 'content': '8', 'action': 'value' }, { 'content': '9', 'action': 'value' }, typeKey, { 'content': '0', 'action': 'value' }, { 'content': '←', 'action': 'delete' } ]; } _renderKeyboard(container) { const { clearName } = this.options; let className = ''; let keyboards = this.items.map((item) => { switch (item.content) { case 'X': className = s.keyX; break; case clearName: className = s.keyClear; break; case '←': className = s.keyDelete; break; default: className = ''; break; } return ``; }); const keyboardBox = document.createElement('div'); keyboardBox.className = `${s.keyboard} ${this.options.className}`; keyboardBox.innerHTML = keyboards.join(''); keyboardBox.addEventListener('touchend', (e) => { let {action, content} = e.target.dataset; this.handleClick(action, content); }); container.appendChild(keyboardBox); } init(options) { this.handleClearName(); this.initKeys(options.type); this._renderKeyboard(options.el); } } export default DigitalKeyboard; ================================================ FILE: src/Keyboard.scss ================================================ $fontFamily: PingFang-SC, "San Francisco", "Source Sans", Rotobo, "Helvetica Neue"; @mixin hlh($height) { height: $height; line-height: $height; } .keyboard { display: flex; flex-wrap: wrap; justify-content: space-around; font-family: $fontFamily; font-size: 12px; button { width: calc(100% /3); @include hlh(2.17em); font-family: $fontFamily; font-size: 2em; text-align: center; color: #3f3f3f; border:0; background-color: #fff; cursor: pointer; touch-action: none; -webkit-tap-highlight-color: rgba(0,0,0,0); &:focus { outline: none; } &:active { background-color: #dfdfdf; } &.keyClear { @include hlh(2.89em); font-size: 1.5em; } &.keyDelete{ font-weight: bold; } &.keyX{ @include hlh(2.55em); font-size: 1.7em; } } } ================================================ FILE: src/main.js ================================================ import DigitalKeyboard from './Keyboard'; // import DigitalKeyboard from 'digital-keyboard'; import s from './main.scss'; function inputValue(value) { document.querySelector('#values').innerHTML = value; } document.querySelector('#clear').addEventListener('click', clearValue); function clearValue() { Keyboard.value = ''; } let Keyboard = new DigitalKeyboard({ el: document.querySelector('#app'), className: s.container, type: 'integer', inputValue: inputValue, integerDigits: 4, decimalDigits: 2, language: 'english' }); ================================================ FILE: src/main.scss ================================================ .container { color: #bbbbbb; } ================================================ FILE: test/Keyboard.test.js ================================================ const expect = require('chai').expect, {JSDOM} = require('jsdom'), {window} = new JSDOM(` 数字键盘
`); propagateToGlobal(window); function propagateToGlobal(window) { for (let key in window) { if (!window.hasOwnProperty(key)) continue; if (key in global) continue; global[key] = window[key]; } } const DigitalKeyboard = require('../build/Keyboard').default; describe('mocha tests', function() { let inputValue, currentValue = '', tempValue = ''; before(function() { inputValue = function(value) { document.querySelector('#values').innerHTML = value; currentValue = value; }; }); ['idcard', 'integer', 'phone', 'normal'].forEach(function(keyboardType) { it('render correct', function() { tempValue = ''; switch (keyboardType) { case 'integer': new DigitalKeyboard({el: document.querySelector('#app'), type: keyboardType, inputValue: inputValue}); expect(document.querySelectorAll('button')[9].innerHTML).be.equal('清空'); break; case 'phone': new DigitalKeyboard({el: document.querySelector('#app'), type: keyboardType, inputValue: inputValue}); expect(document.querySelectorAll('button')[9].innerHTML).be.equal('清空'); break; case 'idcard': new DigitalKeyboard({el: document.querySelector('#app'), type: keyboardType, inputValue: inputValue}); expect(document.querySelectorAll('button')[9].innerHTML).be.equal('X'); break; default: new DigitalKeyboard({el: document.querySelector('#app'), type: keyboardType, inputValue: inputValue}); expect(document.querySelectorAll('button')[9].innerHTML).be.equal('.'); break; } }); it('get correct value', function() { document.querySelectorAll('button').forEach(function(itemKey) { let event = document.createEvent('HTMLEvents'); event.initEvent('touchend', true, true); itemKey.dispatchEvent(event); let action = itemKey.getAttribute('data-action'), content = itemKey.getAttribute('data-content'); switch (action) { case 'delete': tempValue = tempValue.substr(0, tempValue.length - 1); break; case 'clear': tempValue = ''; break; default: switch (keyboardType) { case 'phone': if (tempValue.length < 11) { tempValue += content; } break; case 'idcard': if (tempValue.length < 18) { tempValue += content; } break; default: tempValue += content; } break; } expect(currentValue).to.be.equal(tempValue); }); document.querySelector('#app').innerHTML = ''; }); }); });