JavaScript를 사용하여 Safari에서 키보드 이벤트 실행


79

JavaScript를 사용하여 Safari에서 키보드 이벤트를 시뮬레이션하려고합니다.

나는 이것을 시도했다 :

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

... 그리고 이것도 :

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

그러나 두 가지 접근 방식을 모두 시도한 후 동일한 문제가 발생합니다. 코드가 실행 된 후 이벤트 개체 의 keyCode/ which속성이로 설정 0되지 않습니다 115.

누구든지 Safari에서 키보드 이벤트를 안정적으로 만들고 전달하는 방법을 알고 있습니까? (가능한 경우 일반 JavaScript로 달성하는 것을 선호합니다.)


정의한 코드 나 브라우저가 이해하는 키 조합을 실행하려고합니까? 자체 코드 인 경우 여기에서 설명한대로 "실제"키보드 인터페이스 또는 다른 이벤트 생성기를 통해 호출 할 수있는 이벤트 래퍼를 설정하는 것이 가장 좋습니다. 적절한 리팩토링.
Nolte 2009-06-07

1
이 예에서는 사용자가 "s"를 누르는 것을 시뮬레이션하려고합니다. 궁극적으로 저는 Apple Dashboard Widget에서 Command-R을 누르는 사용자를 시뮬레이션하려고합니다.
Steve Harrison

2
귀하의 코드가 내 문제를 해결했습니다. :)

@ acidzombie24 : 반갑습니다! :)
Steve Harrison

답변:


43

내가 일하고 DOM 키보드 이벤트 레벨 3 polyfill . 최신 브라우저 또는이 polyfill을 사용하여 다음과 같이 할 수 있습니다.

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})

최신 정보:

이제 내 polyfill은 기존 속성 "keyCode", "charCode"및 "which"를 지원합니다.

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

여기에

또한 여기에는 내 polyfill과 별도로 브라우저 간 initKeyboardEvent가 있습니다. (요점)

Polyfill 데모


스크롤 가능 영역을 화살표 또는 페이지 위 / 아래 키를 사용하여 아래로 스크롤하는 데 작동하지 않는 것 같습니다.
Michael

문서 @ jsfiddle.net/vnathalye/yjc5F/974 대신 텍스트 상자에 이벤트를 전달하도록 jsfiddle을 변경 했습니다 . 키 누르기 핸들러를 실행하지만 텍스트는 텍스트 상자에 표시되지 않습니다. 어떤 생각?
Vivek Athalye

1
@termi 데모 링크가 죽었
세바스찬

입력 (텍스트) 요소의 값을 변경하는데도 작동하지 않는 것 같습니다.
Michael

삭제 연산자의 피연산자는 읽기 전용 속성이 될 수 없습니다.
nircraft

30

이벤트를 올바르게 전달 했습니까?

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");
  }
}

jQuery를 사용하는 경우 다음을 수행 할 수 있습니다.

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

3
이것으로 제어 + C (바로 가기 복사)를 시뮬레이션 할 수 있습니까?
John John Pichler 2013 년

1
@claudiopro 예, 맞아야합니다(evt.initKeyEvent || evt.initKeyboardEvent).call(evt, // etc.
tyronegcarter

12
initKeyboardEvent는 Chromium에서도 작동하지 않습니다. event.keyCode그리고 event.which항상 A의 0을 반환 알려진 버그 와 해결 방법은 정기적 인 이벤트를 사용하는 것입니다var event = document.createEvent('Event'); event.initEvent('keydown', true, true); event.keyCode = 76;
lluft

5
을 downvoted : initKeyEvent하고 initKeyboardEvent있습니다 중지됨 .
Константин Ван 2011

2
@ K._ 이전에 작동하던 답변에 대해 반대표를 던지는 대신 tyronegcarter에 부정적인 영향을주지 않으면 서 모든 사람에게주의를 기울일 수 있도록 더 이상 사용되지 않는다고 언급하는 것으로 충분합니다. 이 답변의 stackoverflow.com/questions/961532/...은 현대으로 KeyboardEvent 사용 developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/...을
비트 덜

17

이것은 Webkit 의 버그 때문 입니다.

createEvent('Event')대신을 사용하여 Webkit 버그를 해결 createEvent('KeyboardEvent')한 다음 keyCode속성 을 할당 할 수 있습니다. 참조 이 답변 하고 이 예제를 .


8

모질라 개발자 네트워크는 다음과 같은 설명을 제공합니다 :

  1. 다음을 사용하여 이벤트 만들기 event = document.createEvent("KeyboardEvent")
  2. keyevent 초기화

사용 :

event.initKeyEvent (type, bubbles, cancelable, viewArg, 
       ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, 
           keyCodeArg, charCodeArg)
  1. 다음을 사용 하여 이벤트 를 전달합니다.yourElement.dispatchEvent(event)

나는 당신의 코드에서 마지막 것을 보지 못합니다. 아마도 그것이 당신이 놓친 것입니다. 나는 이것이 IE에서도 작동하기를 바랍니다.


2
불행히도 Mozilla의 구현은 표준이 아닙니다. 포인트 3의 경우 내 문제는 올바른 이벤트를 생성하는 것입니다. 이벤트를 발송하는 것은이 후에 발생합니다. 또한 Apple의 Dashboard를 위해 개발 중이므로 IE에 대해 전혀 걱정할 필요가 없습니다! (Whoopee!)
Steve Harrison

5
.initKeyEvent이제 사용되지 않습니다
Hampus Ahlgren

1

나는 이것에별로 좋지 않지만 KeyboardEvent=> KeyboardEvent is initialized with initKeyEvent.
다음은 <input type="text" />요소에서 이벤트를 생성하는 예입니다.

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
그것은 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)사파리에서 보여줍니다 :(
He Yifei 何 一 非

다음과 같아야합니다. var kEvent = document.createEvent ( "KeyboardEvent"); kEvent.initKeyboardEvent ( "keypress", true, true, null, false, false, false, false, 74, 74); document.dispatchEvent (kEvent);
Любопытный
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.