3

Javascript アプリケーション用のオンスクリーン キーボードを実装しています。テキストは textarea-Element に表示されます。テキスト イベントの作成には問題はありませんが、Backspace などの非テキスト イベントを作成できないと感じています。サンプルコードは次のとおりです。

    <html>
    <頭>
    <title>Textarea イベントのテスト</title>
    <script type="text/javascript">
    関数ログ(テキスト) {
        var elem = document.getElementById("ログ");
        if (要素) {
            elem.innerHTML += "<br/>" + テキスト;
        }
    }
    関数 logEvent(e) {
        log("Type: " + e.type + ", which: " + e.which + ", keyCode: " + e.keyCode + ", charCode: " + e.charCode + ", keyIdentifier: " + e.keyIdentifier + "、データ: " + e.data);
    }
    関数 logClear() {
        var elem = document.getElementById("ログ");
        if (要素) {
            elem.innerHTML = "";
        }
    }
    関数 sendBackEvent() {
        var textarea = document.getElementById("textarea");
        if(!テキストエリア) {
            戻る;
        }
        var ke1 = document.createEvent("KeyboardEvent");
        ke1.initKeyboardEvent("keydown", true, true, window, "U+0008", 0, ""); // U+0008 --> バックスペース
        // "keyCode" と "which" を設定する方法は?
        // 1. ke1.keyCode = 8; "writable: false" のため無視されます
        // 2. ke1.keyCode の削除も無視されます
        // そして Object.defineProperty(KeyboardEvent.prototype, "keyCode", ... なんでも ...);
        // "configurable: false" により例外が発生します
        // 3. より一般的なイベントの生成 (例: "var e = document.createEvent("Events");")
        // 必要なすべての小道具を設定します (例: "e.initEvent("keydown", true, true);e.keyCode=8;e.which=8;")
        // 動作しますが、テキストエリアはイベントを無視します
        textarea.dispatchEvent(ke1);

        var ke2 = document.createEvent("KeyboardEvent");
        ke2.initKeyboardEvent("keyup", true, true, window, "U+0008", 0, ""); // U+0008 --> バックスペース
        // 上記と同じ質問
        textarea.dispatchEvent(ke2);
    }
    関数init() {
        var textarea = document.getElementById("textarea");
        if(!テキストエリア) {
            戻る;
        }
        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()">BackEvent を送信</button>
    <button onclick="logClear()">ログをクリア</button><br/>
    <div id="ログ"></div>
    </body>
    </html>

ここで興味深い関数はsendBackEvent(). 物理キーボードの Backspace ボタンを押すなど、まったく同じイベントを取得しようとしましたが、成功しませんでした。

Webkit-Bugがあることは知っていますが、これを機能させる別の方法があることを願っています。誰かが同じ問題を抱えていますか?それは解決できますか?どのように?ここで提案されているソリューション( new を呼び出すKeyboardEvent(...)) は機能しません。KeyboardEvent コンストラクターを直接呼び出すと、次の例外が発生するためです。

例外: TypeError: '[object KeyboardEventConstructor]' はコンストラクターではありません ('new KeyboardEvent(...)' を評価しています)

もうアイデアはありません。

4

1 に答える 1

3

逃げ道がないように思われるので、私は自分自身のバックスペースイベントハンドラーをインストールすることを強いられていることに気づきました。動作するコード(今はログに記録されていません)は次のとおりです。

    <html>
    <頭>
    <title>テキストエリアイベントのテスト</title>
    <script type = "text / javascript">
    関数sendBackEvent(){
        var textarea = document.getElementById( "textarea");
        if(!textarea){
            戻る;
        }
        var ke1 = document.createEvent( "Events");
        ke1.initEvent( "keydown"、true、true);
        ke1.keyCode = ke1.which = 8; //バックスペース
        textarea.dispatchEvent(ke1);

        var ke2 = document.createEvent( "Events");
        ke2.initEvent( "keyup"、true、true);
        ke2.keyCode = ke2.which = 8; //バックスペース
        textarea.dispatchEvent(ke2);
    }
    関数handleBackEvent(e){
        if(e.keyCode!= 8){
            戻る;
        }
        if(textarea.value.length == 0){
            戻る;
        }
        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();
        falseを返します。
    };
    var textarea;
    関数init(){
        textarea = document.getElementById( "textarea");
        if(!textarea){
            戻る;
        }
        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()">バックイベントを送信</ button>
    </ body>
    </ html>

他の誰かが同じ問題に遭遇した場合に備えて。

于 2013-01-09T13:49:03.350 に答える