For some reason, my stimulus controller, load once, but the action is fired twice on click.
I can't find where the issue is...

我的代码很简单,所以我在下面分享一下:

// app/javascript/application.js
https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"

// app/javascript/controllers/application.js
import { Application } from "@hotwired/stimulus"
const application = Application.start()
application.debug = false
window.Stimulus   = application
export { application }
// app/javascript/controllers/index.js
import { application } from "controllers/application"
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)
// app/javascript/controllers/radio_button_controller.js

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static classes = [ 'active', 'inactive', 'invisible' ]

  connect() {
    console.log('connected to ', this.element.querySelector('input').value)
  }

  markAsChecked(event) {
    event.stopPropagation();
    console.log('-', this.element.querySelector('input').value);
  }
}
// view.html.erb

<div class="flex flex-1 gap-x-8 justify-start">
  <label data-controller="radio-button" data-action="click->radio-button#markAsChecked:stop">
    <input type="radio" value="public" name="destination[access_type]" id="destination_access_type_public">
  </label>
  <label data-controller="radio-button" data-action="click->radio-button#markAsChecked:stop">
    <input type="radio" value="private" name="destination[access_type]" id="destination_access_type_private">
  </label>
  <label data-controller="radio-button" data-action="click->radio-button#markAsChecked:stop">
    <input type="radio" value="backend" name="destination[access_type]" id="destination_access_type_backend">
  </label>
</div>

当我在开发人员控制台中运行以下命令时,我也得到了双重动作触发

// developer console
temp1 // label
temp1.click()
// - public
// - public
temp2 // input
temp2.click()
// - public

As you can see, markAsChecked is triggered twice when I click on the label, and once when I click on the input. I have no idea why...
(I expect it to always trigger once)

推荐答案

这是默认的<label>元素行为:

当用户点击或touch /轻击标签时,浏览器将焦点转移到其关联的输入(the resulting event is also raised for the input)...

100

...单击下面代码片段中的label可以触发用户代理到fire a 101 event at the 102元素,就像元素本身被用户触发一样:

<label><input type=checkbox name=lost> Lost</label>

100


请注意,当单击<label>时,您会看到两个事件,但event.target不同:

document.addEventListener("click", (event) => {
  console.log(event.target);
})
<label for="destination_access_type_public">click me</label>
<input type="radio" value="public" name="destination[access_type]" id="destination_access_type_public">

您可以将data-actioninput相加,以始终获得单个事件:

<label data-controller="radio-button">
  <input data-action="click->radio-button#markAsChecked" type="radio" value="public" name="destination[access_type]" id="destination_access_type_public">
</label>

Javascript相关问答推荐

如何用显示网格平滑地将元素从一个地方移动到另一个地方?

将状态向下传递给映射的子元素

我不知道为什么setwritten包装promise 不能像我预期的那样工作

如何从调整大小/zoom 的SVG路径定义新的d属性?""

使用Java脚本根据按下的按钮更改S文本

这个值总是返回未定义的-Reaction

在HTML语言中调用外部JavaScript文件中的函数

用JS从平面文件构建树形 struct 的JSON

扩展类型的联合被解析为基类型

将Node.js包发布到GitHub包-错误ENEEDAUTH

Vaadin定制组件-保持对javascrip变量的访问

Google脚本数组映射函数横向输出

try 将Redux工具包与MUI ToggleButtonGroup组件一起使用时出错

FileReader()不能处理Firefox和GiB文件

如何更改Html元素S的 colored颜色 ,然后将其褪色为原始 colored颜色

如何使用[ModelJSON,ArrayBuffer]调用tf.loadGraphModelSync

Chart.js Hover线条在鼠标离开时不会消失

如何使pdf.js上的文本呈现为可选?

使用VITE开发服务器处理错误

观察子组件中的@Output事件emits 器?