Android不会在keydown事件上触发event.preventDefault()

时间:2018-03-26 08:19:51

标签: javascript android html5 reactjs input

它是html5输入的包装器,带有自定义验证。遇到输入类型编号的无数限制,我决定切换到文本类型。不幸的是,这个应用程序必须在移动环境中运行,客户要求当用户专注于输入时,数字键盘会出现。我尝试使用onFocus和onBlur事件实现动态类型切换,这些事件在iOS设备上运行良好。然而,此代码在Android设备上中断:似乎类型不会更改,并且正则表达式不会应用于输入。

我正在创建一个反应输入组件

class InputNumber extends Component {
    constructor(props) {
        super(props);
        this.re = props.regex ? props.regex : /^(?:[1-9]\d*(?:\.\d{0,2})?)?$/;
    }
    componentWillReceiveProps(nextProps) {
        // check new props and reassign the stake if needed
        if (this.input && this.currentVal !== nextProps.newValue) {
            if (nextProps.newValue === "0") {
                this.input.value = "";
            } else {
                this.input.value = nextProps.newValue;
            }
        }
    }

    makeTypeText = e => {
        e.target.type = "text";
    };

    makeTypeNumber = e => {
        e.target.type = "number";
    };

    setValue = e => {
        const re = this.re; // pattern that we will validate our input against
        const currentVal = e.target.value.split(""); // in order to validate we need to know what would be the next value
        const newChar = e.key; // we transform the current value into an array and
        let nextVal = [...currentVal]; // create a new array with previous values
        const start = e.target.selectionStart; // and then place the input char into the current cursor position
        const end = e.target.selectionEnd;
        if (e.key === "Backspace") {
            // if backspace is typed
            if (start === end) {
                nextVal.splice(start - 1, 1); // if there is no selection just delete the digit before the cursor
            } else {
                nextVal.splice(start, end - start); // if the user has selected several digits just replace them with empty string
            }
        } else if (e.key === "Delete") {
            // if delete is typed
            if (start === end) {
                nextVal.splice(start, 1); // delete a digit before after  the cursor if no selection
            } else {
                nextVal.splice(start, end - start); // delete selection
            }
        } else {
            nextVal.splice(start, end - start, e.key); // insert digit before the cursor or replace selection with a digit
        }
        const valueAfterInput = nextVal.join("");
        // check the value that would result from input against the regular expression
        if (!re.test(valueAfterInput)) {
            e.preventDefault(); // if the next value is invalid we prevent the user action
        } else {
            this.currentVal =
                valueAfterInput.slice(-1) === "."
                    ? valueAfterInput.substr(0, valueAfterInput.length - 1)
                    : valueAfterInput; // assign the current value to a class variable so we can check it against incoming props
            this.props.action(valueAfterInput); // dispatch an action
        }
    };
    render() {
        return (
            <div className="form-field__input">
                <input
                    type="number"
                    onKeyDown={this.setValue}
                    onFocus={this.makeTypeText}
                    onBlur={this.makeTypeNumber}
                    ref={input => (this.input = input)}
                    className={cn("form-input", "form-input_focus", {
                        "form-input_orange": this.props.hideCurrency
                    })}
                    placeholder={t("Stake...")}
                />
                <span
                    className={cn(
                        "form-field__action",
                        "form-field__action_showed",
                        "form-field__action_text",
                        {hidden: this.props.hideCurrency}
                    )}
                >
                    ₽
                </span>
            </div>
        );
    }
}

InputNumber.propTypes = {
    newValue: PropTypes.string,
    hideCurrency: PropTypes.bool.isRequired,
    action: PropTypes.func.isRequired,
    regex: PropTypes.object
};

export default InputNumber;

有关如何纠正这种情况的任何想法?

P.S。:在理解问题之前停止标记为重复。

0 个答案:

没有答案