Javascript 在Ember中,使用select标记停止单击事件传播的最佳方法是什么
在Ember中,我希望有一个父div,当单击时将调用一个操作,除非在该div中单击了一个select标记。我最终想出了一个解决方案,但它不是很好,我想知道是否有人能解释为什么在这种情况下bubbles=false不起作用,以及我如何能够访问selectValue操作上的事件(详情如下) 最初我有:Javascript 在Ember中,使用select标记停止单击事件传播的最佳方法是什么,javascript,html,ember.js,Javascript,Html,Ember.js,在Ember中,我希望有一个父div,当单击时将调用一个操作,除非在该div中单击了一个select标记。我最终想出了一个解决方案,但它不是很好,我想知道是否有人能解释为什么在这种情况下bubbles=false不起作用,以及我如何能够访问selectValue操作上的事件(详情如下) 最初我有: <div class="parent-class" {{action 'shouldNotBeCalledOnSelect'}}> <select onchange={{ac
<div class="parent-class" {{action 'shouldNotBeCalledOnSelect'}}>
<select onchange={{action "selectValue" value="target.value"}}>
<option class="default-option" disabled selected value>-</option>
{{#each score.range as |valueChoice|}}
<option value={{valueChoice}} selected={{eq score.value valueChoice}}>{{valueChoice}}</option>
{{/each}}
</select>
</div>
通过操作,您可以使用
onclick={{action 'someAction'}}
然后可以在Javascript中检索事件作为最后一个参数。我实现的解决方案有点垃圾,就是在select标记上同时包含onchange和onclick事件,并专门使用onclick停止传播
<div class="parent-class" {{action 'shouldNotBeCalledOnSelect'}}>
<select onchange={{action "selectValue" value="target.value"}} onclick={{action 'stopPropagation'}}>
<option class="default-option" disabled selected value>-</option>
{{#each score.range as |valueChoice|}}
<option value={{valueChoice}} selected={{eq score.value valueChoice}}>{{valueChoice}}</option>
{{/each}}
</select>
</div>
您可以通过动作助手的
bubbles=false
参数来停止事件传播。但是在onchange
动作处理程序中,您不能停止onclick
事件冒泡。因此,在您的用例中,您只需定义noop函数并定义bubbles=false
。
你的解决方案是唯一的出路(AFAIK)
首先,您需要同时处理
onclick
和onchange
;因为它们是不同的事件,冒泡到div元素的事件是onclick
。不能通过阻止onchange
事件冒泡来阻止click事件传播到div元素
其次,kumkanillam提供的答案不起作用!!!请参见我在哪里尝试kumkanillam提出的解决方案,以及在第一次和第二次选择中分别使用bubbles=false
的正确方法
这就是为什么bubbles=false
不适用于Ember官方API中的第一个选择,而适用于第二个选择的原因。“要禁用闭包式操作冒泡,您必须创建自己的包装器帮助程序,使用event.stopPropagation()”。有关详细信息,请参阅
总而言之,如果您使用闭包操作(这是您最初发布的情况),则必须编写一个操作处理程序并调用event.stopPropagation()
,以防止事件冒泡。如果您使用老式的操作帮助器(twiddle中的第二个选择),则冒泡=false
将起作用
您可以在下面阅读有关操作帮助程序的更多信息,以了解有关操作帮助程序的更多信息。您的解决方案将不起作用;因为
bubbles=false
不适用于关闭操作。它仅适用于旧式操作。您需要调用event.stopPropagation()
有关闭包操作。有关详细信息,请参阅我的答案。在我的测试中,我实际上是在没有闭包的情况下完成的,因此它工作正常。但在回答时,我复制了OP的代码,并陷入了相同的陷阱(闭包式操作无法阻止事件冒泡)。谢谢你指出。有时会更新我的答案,不用担心。谢谢你的回答和解释。我有很多东西要读。我的声誉不高,不足以提高投票率,但到时候我会的。
<div class="parent-class" {{action 'shouldNotBeCalledOnSelect'}}>
<select onchange={{action "selectValue" value="target.value"}} onclick={{action 'stopPropagation'}}>
<option class="default-option" disabled selected value>-</option>
{{#each score.range as |valueChoice|}}
<option value={{valueChoice}} selected={{eq score.value valueChoice}}>{{valueChoice}}</option>
{{/each}}
</select>
</div>
selectValue(value) {
this.set('score.value', value);
this.get('score').save();
},
stopPropagation(event) {
event.stopPropagation();
},
shouldNotBeCalledOnSelect() {
console.log("CALLED");
}
<div class="parent-class" {{action 'shouldNotBeCalledOnSelect'}}>
<select onchange={{action "selectValue" value="target.value"}} {{action 'fnToStopPropagation' bubbles=false}}>
<option class="default-option" disabled selected value>-</option>
{{#each score.range as |valueChoice|}}
<option value={{valueChoice}} selected={{eq score.value valueChoice}}>{{valueChoice}}</option>
{{/each}}
</select>
</div>
fnToStopPropagation() {
}