/*-- 海皮智造 虚拟键盘 20200930 ============================================= React 内调用说明: import { VirtualKeyboard } from './VK' VirtualKeyboard 有2个参数,3个方法。 // 参数1: VirtualKeyboard.isDisableEnter=true|false 是否禁用Enter键,默认为true。 参数2: VirtualKeyboard.isDisableTab=true|false 是否禁用Tab键,默认为true。 ------------------------ 方法1: .showKeyboardSetState(valueObject,reactComponent) 显示虚拟键盘,此方式主要用于Antd Input组件,由于Antd的输入组件直接修改dom的value不生效,故只能传入值Object对象。 valueObject 是一个Object,Object对象必须使用value属性来传递值。 reactComponent 是当前React Component,用于按键后setState更新显示。 如下例子: let V={value:'123'} VirtualKeyboard.showKeyboardSetState(V,this)} value={V.value}/> 方法2: .showKeyboard(e) 显示虚拟键盘,此方式主要用于大部分模式。 参数e可是3种类型, 1、字符串,即要联动的dom的id 使用举例: VirtualKeyboard.showKeyboard("inputA") 2、直接是要联动的dom对象, 使用举例: VirtualKeyboard.showKeyboard(document.getElementById("xxx")) 3、鼠标/触摸事件 使用举例: 方法3: .closeKeyboard() 用命令来关闭键盘,一般来说用不到。 --*/ import React from 'react'; import ReactDOM from 'react-dom'; import * as commonUtils from '../../utils/utils'; class VK extends React.Component { constructor(props) { super(props); if (props.values.dom !== null) { this.V.currentDom = props.values.dom; } if (props.values.value !== null && props.values.state !== null) { this.V.reactValueObject = props.values.value; this.V.reactStateObject = props.values.state; } const w = document.body.clientWidth; // const h = document.body.clientHeight; // eslint-disable-next-line no-mixed-operators // this.V.x = w / 2 - 970 / 2; // this.V.y = h - 300; this.V.x = w - 214; this.V.y = 10; } // eslint-disable-next-line react/sort-comp // C = [ // '~`', '!1', '@2', '#3', '$4', '%5', '^6', '&7', '*8', '(9', ')0', '_-', '+=', 'Backspace', // 'Tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{[', '}]', '|\\', // 'CapsLock', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'L', 'L', ':;', "\"'", 'Enter', // 'Shift', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<,', '>.', '?/', 'Space']; // eslint-disable-next-line react/sort-comp C = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0', '←', ]; // eslint-disable-next-line no-sparse-arrays W = [, , , , , , , , , , , , , 120, 90, , , , , , , , , , , , , 90, 110, , , , , , , , , , , , 135, 140, , , , , , , , , , , 170] componentWillReceiveProps(nextProps) { if (nextProps.values.dom !== null) { this.V.currentDom = nextProps.values.dom; this.V.reactValueObject = null; this.V.reactStateObject = null; } else if (nextProps.values.value !== null && nextProps.values.state !== null) { this.V.reactValueObject = nextProps.values.value; this.V.reactStateObject = nextProps.values.state; this.V.currentDom = null; } } getComponentFocus = () => { const { inputRef, state } = this.props.values; let componentId = ''; if (commonUtils.isNotEmptyObject(state.props.showConfig)) { componentId = state[inputRef].props ? state[inputRef].props.id : state[inputRef].getAttribute('id'); } else { componentId = inputRef; } // 获取光标 if (commonUtils.isNotEmptyStr('inputRef') && document.getElementById(`${componentId}`) !== null) { document.getElementById(`${componentId}`).focus(); } else { console.log('没有获得id'); } } // eslint-disable-next-line camelcase F_ChangeInput = (c) => { let inputContent = ''; if (this.V.currentDom !== null) { inputContent = this.V.currentDom.innerText || this.V.currentDom.textContent || this.V.currentDom.value; } else inputContent = this.V.reactValueObject.value; inputContent = inputContent.toString(); const strArr = inputContent.split(''); if (c === -1) { strArr.pop(); } else strArr.push(c); if (this.V.currentDom !== null) { if (this.V.currentDom.nodeName === 'INPUT') { this.V.currentDom.value = strArr.join(''); } else if (this.V.currentDom.nodeName !== undefined) { this.V.currentDom.innerHTML = strArr.join(''); } } else if (this.V.reactStateObject !== null && this.V.reactValueObject !== null) { this.V.reactValueObject.value = strArr.join(''); } const { state, inputRef } = this.props.values; const thisProps = state.props; if (commonUtils.isNotEmptyObject(thisProps.showConfig)) { // 走配置,commonComponent组件 const returnValue = {}; if (inputRef.substring(0, 1) === 'd') { if (commonUtils.isNotEmptyStr(this.V.reactValueObject.value)) { returnValue[thisProps.showConfig.sName] = this.V.reactValueObject.value * 1; } else { returnValue[thisProps.showConfig.sName] = ''; } } else { returnValue[thisProps.showConfig.sName] = this.V.reactValueObject.value; } thisProps.onChange(thisProps.name, thisProps.showConfig.sName, returnValue, thisProps.sId, []); } else if (commonUtils.isNotEmptyObject(state.form)) { // input存在form组件中 state.form.setFields({ [inputRef]: { value: commonUtils.isEmptyStr(this.V.reactValueObject.value) ? '' : this.V.reactValueObject.value * 1, }, }); } else { // 其他类型 state.handleKeyeBoardValueChange(state[inputRef], this.V.reactValueObject.value); } this.getComponentFocus(); }; V = { isCaps: false, isShift: false, currentDom: null, reactValueObject: null, reactStateObject: null, } // eslint-disable-next-line camelcase F_Close = () => { this.props.values.closeKeyboard(); } // eslint-disable-next-line camelcase F_MouseDown = (e) => { e = e.nativeEvent; if (e.button !== 0) return; if (e.target.id.indexOf('VK_') !== 0) { if ((e.target.innerText === 'Enter' && this.props.values.isDisableEnter === true) || (e.target.innerText === 'Tab' && this.props.values.isDisableTab === true)) { return; } e.target.style.backgroundColor = '#F80'; e.target.style.boxShadow = '0px 0px 4px #000 inset'; this.V.keydom = e.target; document.addEventListener('mouseup', this.F_KeyMouseUp); return; } document.addEventListener('mousemove', this.F_MouseMove); document.addEventListener('mouseup', this.F_MouseUp); // this.V.posX = -e.pageX; // this.V.posY = -e.pageY; this.V.posX = -e.pageX; this.V.posY = -e.pageY; } // eslint-disable-next-line camelcase F_MouseMove = (e) => { const tx = this.V.posX + e.pageX + this.V.x; const ty = this.V.posY + e.pageY + this.V.y; this.dom.style.left = `${tx}px`; this.dom.style.top = `${ty}px`; } // eslint-disable-next-line camelcase F_MouseUp = (e) => { this.V.x = this.V.posX + e.pageX + this.V.x; this.V.y = this.V.posY + e.pageY + this.V.y; document.removeEventListener('mousemove', this.F_MouseMove); document.removeEventListener('mouseup', this.F_MouseUp); this.getComponentFocus(); } // eslint-disable-next-line camelcase F_KeyMouseUp = () => { this.V.keydom.style.backgroundColor = '#FFF'; this.V.keydom.style.boxShadow = null; document.removeEventListener('mouseup', this.F_KeyMouseUp); } // eslint-disable-next-line camelcase F_TouchStart = (e) => { e = e.nativeEvent; if (e.target.id.indexOf('VK_') !== 0) { if ((e.target.innerText === 'Enter' && this.props.values.isDisableEnter === true) || (e.target.innerText === 'Tab' && this.props.values.isDisableTab === true)) { return; } e.target.style.backgroundColor = '#F80'; e.target.style.boxShadow = '0px 0px 4px #000 inset'; this.V.keydom = e.target; document.addEventListener('touchend', this.F_KeyTouchEnd); return; } document.addEventListener('touchmove', this.F_TouchMove); document.addEventListener('touchend', this.F_TouchEnd); this.V.posX = -e.targetTouches[0].pageX; this.V.posY = -e.targetTouches[0].pageY; } // eslint-disable-next-line camelcase F_TouchMove = (e) => { const tx = this.V.posX + e.targetTouches[0].pageX + this.V.x; const ty = this.V.posY + e.targetTouches[0].pageY + this.V.y; this.dom.style.left = `${tx}px`; this.dom.style.top = `${ty}px`; } // eslint-disable-next-line camelcase F_TouchEnd = (e) => { this.V.x = this.V.posX + e.changedTouches[0].pageX + this.V.x; this.V.y = this.V.posY + e.changedTouches[0].pageY + this.V.y; document.removeEventListener('touchmove', this.F_TouchMove); document.removeEventListener('touchend', this.F_TouchEnd); } // eslint-disable-next-line camelcase F_KeyTouchEnd = () => { this.V.keydom.style.backgroundColor = '#FFF'; this.V.keydom.style.boxShadow = null; document.removeEventListener('touchend', this.F_KeyTouchEnd); } // eslint-disable-next-line camelcase F_KeyDown = (e) => { const dom = e.target; const txt = dom.innerText; if (txt === 'CapsLock') { this.V.isCaps = !this.V.isCaps; if (this.V.isCaps) { dom.style.backgroundColor = '#F80'; } else { dom.style.backgroundColor = '#FFF'; } this.setState({}); } else if (txt === 'Shift') { this.V.isShift = !this.V.isShift; if (this.V.isShift) { dom.style.backgroundColor = '#F80'; } else { dom.style.backgroundColor = '#FFF'; } this.setState({}); } else if (txt === 'Enter') { if (this.props.values.isDisableEnter === false) { this.F_ChangeInput(String.fromCharCode(13)); } } else if (txt === 'Space') { this.F_ChangeInput(' '); } else if (txt === 'Tab') { if (this.props.values.isDisableTab === false) { this.F_ChangeInput(String.fromCharCode(9)); } } else if (txt === '←') { this.F_ChangeInput(-1); } else if (txt.indexOf('\n') >= 0) { if (this.V.isShift) { this.F_ChangeInput(txt[0]); } else { this.F_ChangeInput(txt[2]); } } else if (this.V.isShift) { this.F_ChangeInput(txt.toUpperCase() === txt ? txt.toLowerCase() : txt.toUpperCase()); } else { this.F_ChangeInput(txt); } } render() { const keyStyle = { boxSizing: 'border-box', float: 'left', height: 60, margin: 2.5, borderRadius: 4, border: '1px solid #333', textAlign: 'center', cursor: 'pointer', }; return (