比如说,我们现在有一个需求,便是帮助用户天生密码,在密码阁下放置一个按钮,点击按钮后密码就被拷贝到粘贴板上了,这样就方便用户利用这个密码了。

打开public/index.html,修正body内容,添补一个大略的按钮,如下:

<div> PIN: <input type="text" value="1234" readonly> <button>Copy to Clipboard</button></div>

html浏览文件按钮Stimulus衔接HTML和Javascript的桥梁实现复制到粘贴板的按钮 Ruby

下一步,创建src/controllers/clipboard_controller.js,然后添加一个copy()方法:

import { Controller } from "@hotwired/stimulus"export default class extends Controller { copy() { }}

然后,给div添加data-controller=“clipboard”。
只假如给元素添加了data-controller属性,Stimulus就会连接一个controller实例。

<div data-controller="clipboard">

我们还须要一个对输入框的引用,这样我们就可以在调用粘贴板API之前获取输入框的内容。
给文本框添加data-clipboard-target=“source“:

PIN: <input data-clipboard-target="source" type="text" value="1234" readonly>

在controller中定义一个target,然后就可以通过this.sourceTarget访问文本框了。

import { Controller } from "@hotwired/stimulus"export default class extends Controller { static targets = [ "source" ] copy() { }}

阐明一下这个targets:

当Stimulus加载你的controller类时,它会查看静态数组targets的字符串元素,对付每一个字符串,Stimulus会在controller中添加3个属性。
在这里,对付“source”,会添加如下属性:

this.sourceTarget 在controller的域内的第一个source

this.sourceTargets 在controller的域内所有的source组成的一个数组

this.hasSourceTarget 在controller的域内是否有source

我们希望点击按钮时调用controller中的copy()方法,以是我们须要添加data-action=“clipboard#copy“

<button data-action="clipboard#copy">Copy to Clipboard</button>

你可以已经把稳到在上面的动作描述符中省略了click->。
那是由于Stimulus给button设置了click作为它默认的事宜。

某些其他元素也有默认事宜。
下面是个全部列表:

元素

默认事宜

a

click

button

click

details

toggle

form

submit

input

input

input type=“submit”

click

select

change

textarea

input

终极,在copy()方法中,我们获取输入框的内容,调用粘贴板API

copy() { navigator.clipboard.writeText(this.sourceTarget.value)}

刷新页面,点击按钮,然后快捷键粘贴到Greet按钮前到输入框,可以看到1234。

到目前为止,在页面上同一韶光只有一个controller实例。
在页面上同时有一个controller的多个实例也是很正常的。

我们的controller是可以复用的,只要你须要在页面上添加复制内容的按钮,无论是哪个页面,只要把对应的属性值写好,我们的controller都是生效的。

还是上面的例子,再添加其余一个复制按钮:

<div data-controller="clipboard"> PIN: <input data-clipboard-target="source" type="text" value="3737" readonly> <button data-action="clipboard#copy" class="clipboard-button">Copy to Clipboard</button></div>

刷新页面,验证一下两个复制按钮是否都生效。

我们再添加一个可以复制的元素,不用button,我们用a标签,

<div data-controller="clipboard"> PIN: <input data-clipboard-target="source" type="text" value="6666" readonly> <a href="#" data-action="clipboard#copy" class="clipboard-button">Copy to Clipboard</a></div>

Stimulus许可我们利用任何元素,只要它设置了得当的data-action属性,就可以触发复制。

这个例子里,要把稳一点,点击链接会使浏览器追踪a标签内的href属性跳转,可以取消这种默认行为,只须要在action中调用 event.preventDefault()就可以了。

copy(event) { event.preventDefault() navigator.clipboard.writeText(this.sourceTarget.value)}

还有其余一个方法,拷贝粘贴板上

copy(event) { event.preventDefault() this.sourceTarget.select() document.execCommand("copy")}

在本文中,我们看了一个在现实中把浏览器API包装在Stimulus的controller中的例子。
还有一个controller的多个实例如何同时涌如今页面上,我们还探索了actions和targets如何保持HTML和JavaScript的疏松耦合。

下一篇文章,我们将优化一下这个复制粘贴板的功能,让它运行起来更加健壮。

Stimulus:浏览器不支持复制或者弱网条件下,怎么办?