当前位置: 首页 > 知识库问答 >
问题:

如何从Javascript在Safari中发送键盘事件(例如Backspace、Delete

淳于开畅
2023-03-14

我正在实现一个Javascript应用程序的屏幕键盘。文本应该出现在textarea元素中。我创建文本事件没有问题,但感觉无法创建非文本事件,如退格键。下面是一些示例代码:


    <html>
    <head>
    <title>Test Textarea Events</title>
    <script type="text/javascript">
    function log(text) {
        var elem = document.getElementById("log");
        if (elem) {
            elem.innerHTML += "<br/>" + text;
        }
    }
    function logEvent(e) {
        log("Type: " + e.type + ", which: " + e.which + ", keyCode: " + e.keyCode + ", charCode: " + e.charCode + ", keyIdentifier: " + e.keyIdentifier + ", data: " + e.data);
    }
    function logClear() {
        var elem = document.getElementById("log");
        if (elem) {
            elem.innerHTML = "";
        }
    }
    function sendBackEvent() {
        var textarea = document.getElementById("textarea");
        if(!textarea) {
            return;
        }
        var ke1 = document.createEvent("KeyboardEvent");
        ke1.initKeyboardEvent("keydown", true, true, window, "U+0008", 0, ""); // U+0008 --> Backspace
        // how to set "keyCode" and "which"?
        //  1. ke1.keyCode = 8; will be ignored due to "writable: false"
        //  2. delete ke1.keyCode will be ignored too
        //     and Object.defineProperty(KeyboardEvent.prototype, "keyCode", ... whatever ...); 
        //     will result in Exception due to "configurable: false"
        //  3. generating a more general Event (e.g. "var e = document.createEvent("Events");")
        //     and setting all necessary props (e.g. "e.initEvent("keydown", true, true);e.keyCode=8;e.which=8;")
        //     will work, but the textarea will ignore the Event
        textarea.dispatchEvent(ke1);

        var ke2 = document.createEvent("KeyboardEvent");
        ke2.initKeyboardEvent("keyup", true, true, window, "U+0008", 0, ""); // U+0008 --> Backspace
        // same question as above
        textarea.dispatchEvent(ke2);
    }
    function init() {
        var textarea = document.getElementById("textarea");
        if(!textarea) {
            return;
        }
        textarea.addEventListener("keydown", logEvent, false);
        textarea.addEventListener("keypress", logEvent, false);
        textarea.addEventListener("keyup", logEvent, false);
        textarea.addEventListener ("textInput", logEvent, false);
    }
    </script>
    </head>
    <body onload="init()">
    <textarea id="textarea" name="text" cols="100" rows="20"></textarea><br/><br/>
    <button onclick="sendBackEvent()">send BackEvent</button>
    <button onclick="logClear()">clear log</button><br/>
    <div id="log"></div>
    </body>
    </html>

这里有趣的函数是sendbackevent()。我试图获得完全相同的事件,如按下物理键盘上的退格键,但没有成功。

我知道有一个Webkit-Bug,但希望有其他的方法来解决这个问题。有人有过同样的问题吗?能解决吗?怎么做?这里建议的解决方案(调用newKeyboardEvent(...))不起作用,因为直接调用KeyboardEvent构造函数会导致以下异常:

异常:TypeError:“[object KeyboardEventConstructor]”不是构造函数(正在计算“New KeyboardEvent(...)”)

我没有更多的想法了。

共有1个答案

公西光华
2023-03-14

由于似乎没有办法,我发现自己不得不安装自己的backspace事件处理程序。工作代码(现在不需要日志记录)在这里:


    <html>
    <head>
    <title>Test Textarea Events</title>
    <script type="text/javascript">
    function sendBackEvent() {
        var textarea = document.getElementById("textarea");
        if(!textarea) {
            return;
        }
        var ke1 = document.createEvent("Events");
        ke1.initEvent("keydown", true, true);
        ke1.keyCode = ke1.which = 8; // Backspace
        textarea.dispatchEvent(ke1);

        var ke2 = document.createEvent("Events");
        ke2.initEvent("keyup", true, true);
        ke2.keyCode = ke2.which = 8; // Backspace
        textarea.dispatchEvent(ke2);
    }
    function handleBackEvent(e) {
        if(e.keyCode != 8) {
            return;
        }
        if (textarea.value.length == 0) {
            return;
        }
        var text = textarea.value;
        var selectionStart = textarea.selectionStart;
        var selectionEnd = textarea.selectionEnd;
        if (selectionStart < selectionEnd) {
            var text1 = (selectionStart > 0 ? text.slice(0, selectionStart) : "");
            var text2 = (selectionEnd < text.length ? text.slice(selectionEnd) : "");
            textarea.value = text1 + text2;
        }
        else if (selectionStart > 0) {
            var text1 = (selectionStart - 1 > 0 ? text.slice(0, selectionStart - 1) : "");
            var text2 = (selectionStart < text.length ? text.slice(selectionStart) : "");
            textarea.value = text1 + text2;
            selectionStart--;
        }
        textarea.selectionStart = textarea.selectionEnd = selectionStart;
        e.preventDefault();
        e.stopPropagation();
        return false;
    };
    var textarea;
    function init() {
        textarea = document.getElementById("textarea");
        if(!textarea) {
            return;
        }
        textarea.addEventListener("keydown", handleBackEvent, false);
    }
    </script>
    </head>
    <body onload="init()">
    <textarea id="textarea" name="text" cols="100" rows="20"></textarea><br/><br/>
    <button onclick="sendBackEvent()">send BackEvent</button>
    </body>
    </html>

以防别人遇到同样的麻烦。

 类似资料:
  • 问题内容: 我可以导入什么以模拟Java中的键盘按下? 因此,例如,我可以使用它制作一个程序,以便在事件发生时自动按下“ a”键。 问题答案: 您需要的一切都在 例:

  • 问题内容: 简短的摘要: 我正在尝试创建一个程序,该程序会将键盘事件发送到计算机,出于所有目的,模拟事件应视为键盘上的实际按键。 原始帖子: 我正在寻找一种使用python生成键盘事件的方法。 假定该函数收到一个必须模拟按下的键,如下所示: 上面显然是示例,但是我要寻找的是库,模块或其他任何可用来模拟键盘事件的库。 注意:这不同于将字符发送到记事本,或在字段等中输入文本。我希望python脚本模拟

  • 问题内容: 我正在使用Java开发屏幕键盘。该键盘的每个可能键都有一个。在按钮上检测到鼠标按下时,我想向当前关注的应用程序发送特定的键盘代码。键盘本身位于无装饰的范围内,并设置为始终在顶部。 我发现Robot类可用于模拟本机队列上的这些键盘事件。但是,在这种情况下,选择表示将在上接收到按键,而我将无法在其他应用程序中接收到它。 如何使屏幕键盘始终保持“无焦点”状态?是否可以使用其他方法发送按键?

  • 问题内容: 我已使用将事件附加到文本框。它工作正常。当我想通过另一个函数以编程方式触发事件时,出现了我的问题。 我该怎么做? 问题答案: 您可以在IE 8或更低版本上使用fireEvent,在大多数。要创建您要触发的事件,可以使用或取决于浏览器。 这是一段不言自明的代码(来自原型),它在上触发事件:

  • 本文向大家介绍javascript中键盘事件用法实例分析,包括了javascript中键盘事件用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例分析了javascript中键盘事件用法。分享给大家供大家参考。具体如下: 键盘事件包含onkeydown、onkeypress和onkeyup这三个事件 事件初始化 DOM标准下 IE下 兼容的方法 使用原则:keydown事件对于功能按键来

  • 本文向大家介绍vue如何监听键盘事件?相关面试题,主要包含被问及vue如何监听键盘事件?时的应答技巧和注意事项,需要的朋友参考一下 方法 addEventListener