如何在ClojureScript中创建按钮元素?

8

我正在尝试在ClojureScript中创建新元素,但似乎无法正常工作。我将从展示一个我在这里找到的例子开始。

(let [dom6238 (.createElement js/document "a")]
    (.setAttribute dom6238 "href" "http://somelink")
    (set! (.-innerText dom6238) "Text")
    dom6238)

他们说这会转化为:
var dom54535 = document.createElement("a");
    dom54535.setAttribute("href", "http://somelink.com");
    dom54535.innerText = "Hello there";
return dom54535

如果我没记错的话,这应该会产生一个类似以下的HTML片段:
[:a.anchor.silly {:href "http://somelink.com"} "Text"]

我在我的.cljs文件中有以下内容:


(defn create-button []
  (let [a (.createElement js/document "a")]
    (.setAttribute a "href" "http://somelink")
    (set! (.-innerText a) "Text")
    a))

(defn init []
  (let [a (.getElementById js/document "write-action")
        b (.getElementById js/document "button-field")]
    (set! (.-innerHTML a)
          "field a")
    (set! (.-innerHTML b)
          (create-button))))

这只是产生了一个按钮字段(button-field),它在HTML中位于写入操作(write-action)上方:

http://somelink/
field a

所以没有锚点标签,只有文本。


我试图创建一个按钮,所以我有以下代码:

(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")
    (set! (.-innerHTML new-button)
          "I'm a button")
    new-button))

这会生成以下输出:
[object HTMLInputElement]
field a

所以,我稍微做了些尝试并删除了返回值:
(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")
    (set! (.-innerHTML new-button)
          "I'm a button")))

这将创建:

I'm a button
field a

再次强调,我只有文本。


而且我必须完整:

(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")))

仅返回文本的方法:

button
field a

并且这个:

(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")
    new-button))

产生如下结果:
[object HTMLInputElement]
field a

我完全迷失了,在各处搜寻解决方案,但似乎没有任何答案能回答这个问题。我尝试将新的设置属性包装在(do)中,并尝试不使用(set!)版本,但都没有创建所需的结果。

问:如何使用ClojureScript创建可点击的按钮?

附加问题:如果有人知道,为什么网站上的示例只返回第一个项目的结果而不是innerText,而我的示例只返回第二个(set!)函数的文本结果?


如果 Ankur 的答案有效,您可以接受它吗? - deterb
1
@deterb 当然可以,但这真的是好的形式吗?我的意思是,这就像我要求你如果我的问题对你有帮助,请给我点赞一样。我之所以不想立即接受它,是因为我曾经看到过答案只是简单地暗示了一下,但从未详细阐述,因为已经选择了另一个答案。因此,我更喜欢在选择答案之前等待几天。如果您查看我的历史记录,我发布的每个主题都有一个选择的答案。 - dizzystar
有趣的角度,我喜欢你的想法。我看到很多人评论答案,然后不选择它,所以当我遇到这种情况时,我会发布一个提醒评论。我会给下一对更多的时间。 - deterb
2个回答

8
你正在将一个DOM元素对象分配给另一个元素的innerHTML属性,这显然是行不通的。你需要使用“appendChild”方法将子元素插入到DOM元素中。
(let [div (.createElement js/document "DIV")]
    (.appendChild div (create-button)))

啊,我现在明白了。之前我使用的是(.appendChild),但是语法有点混乱,因为我把它包裹在(set!)中了。结果发现我可以直接将其附加到已经存在的div上。完美的答案。 - dizzystar

3

Reagent提供了一种从CLJS创建HTML和JS元素的方式,而不必一直调用JS命名空间。我发现这样更容易理解。虽然这是一篇旧文章,但在许多搜索结果中出现,这可能有助于学习的人们。例如:

(defn your-button []
[:div 
    [:input.btn {:type "button" :value "Click Me!"
        :on-click ( your func here ) }]])

CSS:

.btn {

}

在 div 内创建一个按钮,更多信息请参见:https://github.com/reagent-project/reagent


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接