Как получить доступ к свойствам события нажатия клавиши в ClojureScript с помощью каналов?

Используя ClojureScript, я пытаюсь действовать, когда кто-то нажимает enter в текстовом поле, и игнорировать другие клавиши. Поэтому мне нужно иметь возможность различать разные нажатия клавиш.

Для справки, мой ns в моем .cljs:

(ns calculator.calculator
  (:require-macros [cljs.core.async.macros :refer [go]])
  (:require [goog.dom :as dom]
            [goog.events :as events]
            [cljs.core.async :refer [put! chan <!]]
            [clojure.string :as string]))

В моем html есть элемент ввода <input id="data-entry-box"></input>. Я настроил прослушиватель следующим образом:

(defn listen [el type]
  (let [out (chan)]
    (events/listen el type
                   (fn [e] (put! out e)))
    out))

(let [keypresses (listen (dom/getElement "data-entry-box") "keypress")]
  (go (while true
        (let [key-event (<! keypresses)
              char-code (.-charCode key-event)]
          (.log js/console (str "The character code is " char-code))
          (.log js/console (str "The key is " (.-key key-event)))
          (.log js/console (str "The event is " (.-event key-event)))
          (.log js/console (str "Or the event is " (:event key-event)))
          (if (= char-code
                 13)
            (handle-submit))))))

После его компиляции, загрузки страницы и нажатия ввода в элементе ввода я получаю в консоли следующее:

"The character code is 13"
"The key is "
"The event is "
"Or the event is "

Это хорошо; Я могу проверить, что такое ключ, посмотрев значение ASCII, но мне не нужно этого делать. Я хотел бы получить прямой доступ к нажатому символу.

Если я поставлю точку останова, то увижу, что есть свойство .event, а у этого свойства есть еще одно свойство .key. Но я не могу получить к нему доступ, почему-то.


person zck    schedule 14.08.2014    source источник


Ответы (2)


Свойство нажатия клавиши на самом деле не называется .event; это называется .event_. Обратите внимание на подчеркивание в конце. Таким образом, мы получаем к нему доступ с помощью (.-event_ key-event) следующим образом:

(let [keypresses (listen (dom/getElement "data-entry-box") "keypress")]
  (go (while true
        (let [key-event (<! keypresses)
              key-pressed (.-key (.-event_ key-event))]
          (.log js/console (str "The key pressed was " key-pressed))
          (if (= key-pressed
                 "Enter")
            (handle-submit))))))

Этот код печатает: «Нажата клавиша Enter».

Обратите внимание, что в javascript нет символьных литералов, поэтому (.-key (.-event_ key-event)) возвращает строку "Enter".

person zck    schedule 14.08.2014
comment
покажите свой метод прослушивания, я не думаю, что свойство с именем event_. Какой браузер вы используете? Поместите полный рабочий пример кода. Спасибо - person edbond; 14.08.2014
comment
@edbond Я отредактировал его в вопросе, и (по крайней мере, в Firefox 31 и Chromium 36) свойство определенно называется event_. К сожалению, в Chromium подсвойство не key, а keyIdentifier. - person zck; 14.08.2014

Взгляните на код мышеловки — https://github.com/ccampbell/mousetrap/blob/master/mousetrap.js

Обычно используется код клавиши или вручную сопоставляется с «Вводом».

Также я сильно сомневаюсь, что event_ является общим свойством, вы можете обратиться к https://developer.mozilla.org/en-US/docs/Web/Events/keypress

person edbond    schedule 14.08.2014
comment
event_ выглядит так, как будто это ClojureScript (или Google Closure) — он назначается в javascript, сгенерированном компилятором ClojureScript. - person zck; 14.08.2014
comment
Тогда не стоит на это полагаться. В расширенной компиляции он будет заменен чем-то вроде «A», и ваш код не будет работать. - person edbond; 15.08.2014