Kích hoạt sự kiện bàn phím trong Safari, sử dụng JavaScript


79

Tôi đang cố gắng mô phỏng một sự kiện bàn phím trong Safari bằng JavaScript.

Tôi đã thử điều này:

var event = document.createEvent("KeyboardEvent");
event.initKeyboardEvent("keypress", true, true, null, false, false, false, false, 115, 0);

... và cả cái này:

var event = document.createEvent("UIEvents");
event.initUIEvent("keypress", true, true, window, 1);
event.keyCode = 115;

Tuy nhiên, sau khi thử cả hai cách tiếp cận, tôi gặp cùng một vấn đề: sau khi mã được thực thi, các thuộc tính keyCode/ whichcủa đối tượng sự kiện được đặt thành 0, không phải 115.

Có ai biết cách tạo và gửi một sự kiện bàn phím trong Safari một cách đáng tin cậy không? (Tôi muốn đạt được nó bằng JavaScript đơn giản nếu có thể.)


Bạn đang cố gắng thực thi mã bạn đã xác định hoặc một tổ hợp phím nào đó mà trình duyệt hiểu? Nếu đó là mã của riêng bạn, tốt nhất bạn nên thiết lập trình bao bọc sự kiện mà bạn có thể gọi qua giao diện bàn phím "thực" hoặc qua một số trình tạo sự kiện khác, như bạn đã mô tả ở đây. Tái cấu trúc nếu thích hợp.
Nolte

1
Trong ví dụ này, tôi đang cố gắng mô phỏng người dùng nhấn "s". Cuối cùng, tôi đang cố gắng mô phỏng người dùng nhấn Command-R trong Tiện ích bảng điều khiển của Apple.
Steve Harrison

2
Mã của bạn giải quyết vấn đề của tôi :)

@ acidzombie24: Hân hạnh! :)
Steve Harrison

Câu trả lời:


43

Tôi đang làm việc về polyfill Sự kiện Bàn phím DOM Cấp 3 . Trong các trình duyệt mới nhất hoặc với polyfill này, bạn có thể làm như sau:

element.addEventListener("keydown", function(e){ console.log(e.key, e.char, e.keyCode) })

var e = new KeyboardEvent("keydown", {bubbles : true, cancelable : true, key : "Q", char : "Q", shiftKey : true});
element.dispatchEvent(e);

//If you need legacy property "keyCode"
// Note: In some browsers you can't overwrite "keyCode" property. (At least in Safari)
delete e.keyCode;
Object.defineProperty(e, "keyCode", {"value" : 666})

CẬP NHẬT:

Giờ đây, polyfill của tôi hỗ trợ các thuộc tính kế thừa "keyCode", "charCode" và "which"

var e = new KeyboardEvent("keydown", {
    bubbles : true,
    cancelable : true,
    char : "Q",
    key : "q",
    shiftKey : true,
    keyCode : 81
});

Ví dụ ở đây

Ngoài ra, đây là initKeyboardEvent trình duyệt chéo tách biệt với polyfill của tôi: (gist)

Polyfill bản demo


Không có vẻ làm việc để thực hiện một khu vực cuộn cuộn xuống bằng mũi tên hoặc trang lên / xuống phím ...
Michael

Đã thay đổi jsfiddle của bạn để gửi sự kiện trên hộp văn bản thay vì tài liệu @ jsfiddle.net/vnathalye/yjc5F/974 . Mặc dù nó kích hoạt trình xử lý phím bấm, văn bản không được hiển thị trong hộp văn bản. Bất kỳ ý tưởng?
Vivek Athalye

1
@termi liên kết giới thiệu của bạn đã chết
Sebastian

Dường như cũng không hoạt động để thay đổi giá trị của phần tử đầu vào (văn bản).
Michael

Toán hạng của toán tử xóa không được là thuộc tính chỉ đọc.
nircraft

30

Bạn đã gửi sự kiện một cách chính xác?

function simulateKeyEvent(character) {
  var evt = document.createEvent("KeyboardEvent");
  (evt.initKeyEvent || evt.initKeyboardEvent)("keypress", true, true, window,
                    0, 0, 0, 0,
                    0, character.charCodeAt(0)) 
  var canceled = !body.dispatchEvent(evt);
  if(canceled) {
    // A handler called preventDefault
    alert("canceled");
  } else {
    // None of the handlers called preventDefault
    alert("not canceled");
  }
}

Nếu bạn sử dụng jQuery, bạn có thể làm:

function simulateKeyPress(character) {
  jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}

3
Có thể mô phỏng điều khiển + C (sao chép phím tắt) với điều này không?
John John Pichler

1
@claudiopro Vâng, bạn là chính xác nó phải được(evt.initKeyEvent || evt.initKeyboardEvent).call(evt, // etc.
tyronegcarter

12
InitKeyboardEvent cũng không hoạt động trong Chromium. event.keyCodeevent.whichluôn luôn trả 0. Đó là một lỗi được biết và thực hiện giải pháp là sử dụng một sự kiện thường xuyênvar event = document.createEvent('Event'); event.initEvent('keydown', true, true); event.keyCode = 76;
lluft

5
Downvoted : initKeyEventinitKeyboardEventđang KHÔNG DÙNG NỮA .
Константин Ван

2
@ K._ thay vì phản đối cho một câu trả lời đã hoạt động trước đó, nói rằng nó không được dùng nữa sẽ đủ để cung cấp cho mọi người cảnh báo mà không ảnh hưởng tiêu cực đến tyronegcarter. Câu trả lời này stackoverflow.com/questions/961532/… sử dụng KeyboardEvent developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/…
bit-less

17

Điều này là do một lỗi trong Webkit.

Bạn có thể khắc phục lỗi Webkit bằng cách sử dụng createEvent('Event')thay vì createEvent('KeyboardEvent')và sau đó chỉ định thuộc keyCodetính. Xem câu trả lời nàyví dụ này .


8

Các nhà phát triển Mozilla Mạng cung cấp lời giải thích sau đây:

  1. Tạo sự kiện bằng event = document.createEvent("KeyboardEvent")
  2. Init the keyevent

sử dụng:

event.initKeyEvent (type, bubbles, cancelable, viewArg, 
       ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, 
           keyCodeArg, charCodeArg)
  1. Cử sự kiện bằng cách sử dụngyourElement.dispatchEvent(event)

Tôi không thấy cái cuối cùng trong mã của bạn, có thể đó là cái bạn đang thiếu. Tôi hy vọng điều này cũng hoạt động trong IE ...


2
Thật không may, việc triển khai của Mozilla là không chuẩn. Đối với điểm 3, vấn đề của tôi là tạo sự kiện chính xác — việc điều động sự kiện đến sau điều này. Ngoài ra, vì tôi đang phát triển cho Bảng điều khiển của Apple, tôi không phải lo lắng về IE nữa! (Ôi chao!)
Steve Harrison

5
.initKeyEventhiện không được dùng nữa
Hampus Ahlgren

1

Tôi không giỏi lắm với cái này nhưng KeyboardEvent=> thấy KeyboardEvent được khởi tạo bằng initKeyEvent.
Đây là một ví dụ cho sự kiện phát ra trên <input type="text" />phần tử

document.getElementById("txbox").addEventListener("keypress", function(e) {
  alert("Event " + e.type + " emitted!\nKey / Char Code: " + e.keyCode + " / " + e.charCode);
}, false);

document.getElementById("btn").addEventListener("click", function(e) {
  var doc = document.getElementById("txbox");
  var kEvent = document.createEvent("KeyboardEvent");
  kEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 74, 74);
  doc.dispatchEvent(kEvent);
}, false);
<input id="txbox" type="text" value="" />
<input id="btn" type="button" value="CLICK TO EMIT KEYPRESS ON TEXTBOX" />


7
nó hiển thị js:21TypeError: kEvent.initKeyEvent is not a function. (In 'kEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 74, 74)', 'kEvent.initKeyEvent' is undefined)trong safari :(
He Yifei 何 一 非

Nó phải là: var kEvent = document.createEvent ("KeyboardEvent"); kEvent.initKeyboardEvent ("phím bấm", true, true, null, false, false, false, false, 74, 74); document.dispatchEvent (kEvent);
Любопытный
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.