Привязка события Resize к Clojurescript с использованием Jayq

Я пытаюсь создать простой clojurescript, который будет отображать ширину окна браузера.

Мой app.cljs выглядит следующим образом:

(ns acme.frontend.app
(:use [jayq.core :only [$]])
(:require-macros [hiccups.core :as hiccups :refer [html]])
(:require [hiccups.runtime :as hiccupsrt]))

(def $body ($ :body))

(def window-width (atom nil))

(defn on_window_resize
  []
  (reset! window-width (.-innerWidth ($ :window)))
  (println window-width))


(defn init []
  (set! (.-onload ($ :document))
    ((fn []
       (set! (. ($ :window) -resize) (())))))
  (let [$dyncontent ($ :#svgcontent)]
    (.html $dyncontent @window-width))
  (println "ScriptLoaded"))

Мой Shadow-cljs.edn выглядит следующим образом:

{:source-paths
 ["src/dev"
  "src/main"
  "src/test"]

 :dependencies [[cider/cider-nrepl "0.25.10"]
            [jayq "2.5.4"]
            [hiccups "0.3.0"]]
 :builds
 {:frontend
   {:target :browser
    :modules {:main {:init-fn acme.frontend.app/init}}
    :devtools {:http-root "public"
          :http-port 8081}
    :optimizations :advanced
    :externs ["externs/jquery.js"]}}}

Код компилируется, и я вижу main.js в папке public/js.

Однако это ничего не делает. Я могу изменить размер окна так, как мне нравится, ничего не происходит.

Я очень новичок в clojure/script, поэтому, возможно, я делаю что-то глупое. Но что я делаю неправильно?

В качестве примечания, есть ли способ запустить browser-repl в том же файле index.html, который мы сейчас размещаем? Когда я запускаю shadow-cljs browser-repl, открывается новое окно, размещенное на другом порту. Как они могут быть одинаковыми, чтобы разработка шла на одной странице?

ОБНОВЛЕНИЕ С тех пор я немного обновил свой код. Теперь функции init и onDOMLoad выглядят следующим образом:

(defn onDOMLoad
 []
 (.resize ($ :window) on_window_resize))

(defn init []
 (.ready ($ :document) onDOMLoad))

Это ничего не делает при изменении размера.

Однако версия js работает, как показано ниже:

(defn onDOMLoad
 []
 (.addEventListener js/window "resize" on_window_resize))

из этого я предполагаю, что jayq не позволяет вам привязываться к событиям изменения размера. Я лаю не на то дерево?

ОБНОВЛЕНИЕ: теперь я отказался от использования jayq на clojurescript. Вместо этого я считаю, что goog.dom гораздо более удобен для пользователя. Я следую книге по изучению clojurescript для руководства по этому вопросу. Я закрываю этот вопрос соответственно. Большое спасибо.


person user3570501    schedule 12.04.2021    source источник


Ответы (1)


В своем (defn init [] ...) вы создаете анонимную функцию, а затем сразу же вызываете ее, используя дополнительные скобки ((fn [] ...)). Таким образом, результатом вызова этой функции является то, что вы set! называете onload вместо самой функции. Просто удалите одну пару скобок.

В вашей конфигурации вы устанавливаете :optimizations и :externs на неправильном уровне. Они должны быть под ключом :compiler-options. Вам вообще не нужно устанавливать :optimizations, по умолчанию они равны :advanced для сборок браузера release.

browser-repl запускает автономный браузерный REPL, не зависящий от какой-либо сборки. Если вы хотите использовать REPL в своей сборке, используйте shadow-cljs cljs-repl frontend.

person Thomas Heller    schedule 13.04.2021
comment
Привет, Томас! Большое спасибо за ваш ответ. Я внес изменения в shadow-cljs в соответствии с вашими предложениями, и с этого момента я буду использовать shadow-cjls с cljs-repl. Однако проблема с привязкой jayq к изменению размера, похоже, все еще существует. Я обновил свой вопрос, чтобы отразить результаты моих собственных экспериментов с момента публикации исходного вопроса. Еще раз спасибо за вашу помощь!! - person user3570501; 14.04.2021
comment
Я мало что знаю о jayq, но в настоящее время вам, вероятно, лучше просто использовать jquery напрямую без дополнительной оболочки. Только npm install jquery и (:require ["jquery" :as jq]) в вашем ns. Или просто прямое взаимодействие с DOM, такое как ваш addEventListener, тоже подойдет, если только вам не нужно поддерживать действительно исторические браузеры. - person Thomas Heller; 14.04.2021
comment
Спасибо за помощь, Томас. - person user3570501; 17.04.2021