需求

打算在页面中自动填写账号密码,直接给文本框input元素赋值的方式无法触发键盘事件,导致数据不能提交(特殊的场景)。

所以改用javascript的模拟按键事件,但是UIEvent.initUIEvent和KeyboardEvent.initKeyEvent()等方法在最新的Chrome浏览器中已废弃。

按最新标准改用KeyboardEvent构造函数。


一、已废弃方法

最新规范(www.w3.org/TR/DOM-Level-3-Events/)中已弃用KeyboardEvent.initKeyEvent()方法。因此,Chrome没不支持此类方法。

function fireKeyEvent(el, evtType, keyCode) {
            var evtObj;
            if (document.createEvent) {
                if (window.KeyEvent) {//firefox 浏览器下模拟事件
                    evtObj = document.createEvent('KeyEvents');
                    evtObj.initKeyEvent(evtType, true, true, window, true, false, false, false, keyCode, 0);
                } else {//chrome 浏览器下模拟事件
                    evtObj = document.createEvent('UIEvents');
                    evtObj.initUIEvent(evtType, true, true, window, 1);

                    delete evtObj.keyCode;
                    if (typeof evtObj.keyCode === "undefined") {//为了模拟keycode
                        Object.defineProperty(evtObj, "keyCode", { value: keyCode });                       
                    } else {
                        evtObj.key = String.fromCharCode(keyCode);
                    }

                    if (typeof evtObj.ctrlKey === 'undefined') {//为了模拟ctrl键
                        Object.defineProperty(evtObj, "ctrlKey", { value: true });
                    } else {
                        evtObj.ctrlKey = true;
                    }
                }
                el.dispatchEvent(evtObj);

            } else if (document.createEventObject) {//IE 浏览器下模拟事件
                evtObj = document.createEventObject();
                evtObj.keyCode = keyCode
                el.fireEvent('on' + evtType, evtObj);
            }
        }
        

二、推荐方法

<html>
<head>365codes.com</head>
<body>
    <input id="input_username"></input>
</body>
    <script type="text/javascript">
	function fireKeyEvent(element, evtType, keyChar) {
		element.focus();
		var KeyboardEventInit = {key:keyChar, code:"", location:0, repeat:false, isComposing:false};
		var evtObj = new KeyboardEvent(evtType, KeyboardEventInit);
		element.dispatchEvent(evtObj);
	}
	
	var objInput = document.getElementById("input_username");
    objInput.addEventListener('keydown', function (e) {
        objInput.value += e.key;
    }, false);
	
	fireKeyEvent(objInput,"keydown","a");
    </script>
</html>

总结

参考标准文档:键盘事件 KeyboardEvent() - Web API 接口参考 | MDN

特别提醒:代码触发按键事件不会导致该字母自动出现在文本框中,所以在监听keydown事件中增加了input元素赋值,为了UI显示而已。各家浏览器出于安全原因设定,来防止脚本模拟与浏览器本身交互的操作。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐