首页 > 解决方案 > 在VueJs中,如何获取完整单选按钮组的事件@focusout

问题描述

我已经构建了我的自定义单选按钮组组件,它大部分工作正常。但是,当焦点离开任何包含的单选按钮时,我想发出一个“group focusout”事件。

但是,按钮的@focusout都是单独触发的,我找不到确定目标是否在组外的方法。

组件代码

我基本上在做(简化):

<div v-for="(obj, index) in items" :key="index">      
        <label :for="id + '-' + obj.value">
            <input
                :name="name ? name : id"
                :key="index"
                :id="id + '-' + obj.value"
                :value="obj.value"
                :checked="obj.selected"
                @focusout="onFocusout"
                @change="updateRadiobuttons($event.target.value)"
            />
            {{ $t(obj.text) }}
        </label>       
</div>

在@focusout 处理程序中,我进行了一些验证(未显示)并简单地传递事件:

private onFocusout(value) {
    console.debug('onFocusout', value);
    //...validation...
    this.$emit('focusout', value);
}

发出的事件

我正在记录收到的事件并查看日志(使用 Chrome F12)

这是我在无线电组中更改选项时得到的结果:

FocusEvent {isTrusted: true, relatedTarget: input#caseBestaDataSearchResultSchule-3.form-control, view: Window, detail: 0, sourceCapabilities: null, …}
bubbles: true
cancelBubble: false
cancelable: false
composed: true
currentTarget: null
defaultPrevented: false
detail: 0
eventPhase: 0
isTrusted: true
path: (20) [input#caseBestaDataSearchResultSchule-2.form-control, label, div.radio.radio--left, div.radio-inline, div.col-sm-9, div.form-group, div.form-group, fieldset, form.form-horizontal, span, div, div, div#content.col-sm-12, div.row, div.container-fluid, div.container.container-main, body.mod.mod-layout.skin-layout-template-contentpage, html, document, Window]
relatedTarget: input#caseBestaDataSearchResultSchule-3.form-control
returnValue: true
sourceCapabilities: null
srcElement: input#caseBestaDataSearchResultSchule-2.form-control
target: input#caseBestaDataSearchResultSchule-2.form-control
timeStamp: 46397.884999983944
type: "focusout"
view: Window {window: Window, self: Window, document: document, name: "", location: Location, …}
which: 0
__proto__: FocusEvent

这是我点击周围空间时得到的结果:

FocusEvent {isTrusted: true, relatedTarget: null, view: Window, detail: 0, sourceCapabilities: InputDeviceCapabilities, …}
bubbles: true
cancelBubble: false
cancelable: false
composed: true
currentTarget: null
defaultPrevented: false
detail: 0
eventPhase: 0
isTrusted: true
path: (20) [input#caseBestaDataSearchResultSchule-3.form-control, label, div.radio.radio--left, div.radio-inline, div.col-sm-9, div.form-group, div.form-group, fieldset, form.form-horizontal, span, div, div, div#content.col-sm-12, div.row, div.container-fluid, div.container.container-main, body.mod.mod-layout.skin-layout-template-contentpage, html, document, Window]
relatedTarget: null
returnValue: true
sourceCapabilities: InputDeviceCapabilities {firesTouchEvents: false}
srcElement: input#caseBestaDataSearchResultSchule-3.form-control
target: input#caseBestaDataSearchResultSchule-3.form-control
timeStamp: 54147.71499999915
type: "focusout"
view: Window {window: Window, self: Window, document: document, name: "", location: Location, …}
which: 0
__proto__: FocusEvent

如何获得整个组的单个事件@focusout?

标签: vue.jseventscomponentsfocusout

解决方案


我假设您当前在使用向上和向下箭头循环通过每个收音机时触发焦点事件,或者通过触摸选择另一个选项。

如果是这种情况,您真正了解其他单选按钮的焦点状态的唯一方法是查看它们,使用 ref 将每个元素与 document.activeElement 进行比较或存储每个单选按钮的焦点状态。

如果您有任何活动的焦点课程,您还可以检查课程名称。

下面是使用数据对象存储焦点状态的示例。

另外值得一提的是,您需要在此处使用 nextTick ,否则在您读取数据对象之前数据对象不会更新。

  new Vue({
el: '#app',
data() {
  return {
    maleFocused: false,
    femaleFocused: false,
    otherFocused: false
  } 
},
methods: {
  focusIn(e) {
    this[`${e.srcElement.id}Focused`] = true
  },
  async focusOut(e) {
    this[`${e.srcElement.id}Focused`] = false

    await this.$nextTick()

    const radioMaleFocused = this.maleFocused
    const radioFemaleFocused = this.femaleFocused
    const radioOtherFocused = this.otherFocused
    
    const radiosFocused = radioMaleFocused || radioFemaleFocused || radioOtherFocused
    
    if (!radiosFocused) {
      console.log('run your code here!')
    }
  }
}
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <fieldset>
<legend>Radios</legend>

<input type="radio" id="male" name="gender" value="male" @focusin="focusIn" @focusout="focusOut">
<label for="male">Male</label><br>

<input type="radio" id="female" name="gender" value="female" @focusin="focusIn" @focusout="focusOut">
<label for="female">Female</label><br>

<input type="radio" id="other" name="gender" value="other" @focusin="focusIn"@focusout="focusOut">
<label for="other">Other</label>
  </fieldset>
</div>


推荐阅读