单击 child 时总是 select parent 元素
Always select a parent element when clicking on a child
我有一个 div(标签),里面有 3 个跨度,像这样:
<div class="chat-tabs">
<div class="chat-tabs-cont">
<div id="chat-tab-1" class="chat-tab chat-tab-sel">
<span class="chat-tab-n">1</span>
<span class="chat-tab-t">Tab text 1</span>
<span class="chat-tab-c">11:00</span>
</div>
<div id="chat-tab-2" class="chat-tab">
<span class="chat-tab-n">2</span>
<span class="chat-tab-t">Tab text 2</span>
<span class="chat-tab-c">11:30</span>
</div>
</div>
</div>
这些是选项卡,所以当我单击一个选项卡时,我在 Meteor 中有一个单击事件,为新选项卡提供 class 的 chat-tab-sel
并从中删除此 class旧选项卡(标准选项卡行为)。
我的问题是,根据用户点击的位置,我的 event.target
并不总是 parent div chat-tab
,而是 child span
。我需要 add/remove classes 到 parent div
.
我认为如果 parent 有 display: block
它可能会起作用,但在这种情况下我需要它是 display: flex
因为在 [=32 上有灵活的宽度是有意义的=]s.
所以:是否可以确保当用户点击 child 时 parent div 是有针对性的?
事件气泡。这意味着您可以监听父级上的事件。在事件侦听器中,this
绑定到您将事件侦听器绑定到的元素。所以我们可以监听该元素内的任何点击,然后将当前活动选项卡设置为非活动状态,并将单击的选项卡设置为活动状态。
具体不确定 Meteor,但这就是我使用 vanilla JavaScript.
完成此操作的方式
var tabs = document.querySelectorAll('.chat-tab');
for(var i in Object.keys(tabs)) tabs[i].onclick = function() {
document.querySelector('.chat-tab.chat-tab-sel').className = 'chat-tab';
this.className += ' chat-tab-sel'
}
.chat-tab-sel {
border: 1px solid #012450;
}
<div class="chat-tabs">
<div class="chat-tabs-cont">
<div id="chat-tab-1" class="chat-tab chat-tab-sel">
<span class="chat-tab-n">1</span>
<span class="chat-tab-t">Tab text 1</span>
<span class="chat-tab-c">11:00</span>
</div>
<div id="chat-tab-2" class="chat-tab">
<span class="chat-tab-n">2</span>
<span class="chat-tab-t">Tab text 2</span>
<span class="chat-tab-c">11:30</span>
</div>
</div>
</div>
如果您将普通的 Meteor 事件处理程序与@Brian Shamblen 的提示结合使用,它应该可以正常工作。
Template.myTemplate.events({
'click .chatTab': function(ev){
$(".chat-tab").removeClass("chat-tab-sel"); // remove from all
$(ev.target).closest(".chat-tab").addClass("chat-tab-sel"); // set the one you're on
}
});
基于 Tiny Giant 对事件冒泡的回答,这里是在 meteor 中执行此操作:
Template.theTemplate.events({
'click .chat-tab': function(ev) {
$('.chat-tab').removeClass('chat-tab-sel');
$(ev.currentTarget).addClass('chat-tab-sel');
}
});
这是一篇有趣的 info.meteor.com 博文,其中对此进行了一些详细介绍:
Browser events: bubbling, capturing, and delegation
Suppose you have this HTML structure:
<body>
<p>
<a><span>Hello</span></a>
</p>
</body>
Event delegation is not a browser feature, but a popular technique built into libraries like jQuery. Many blogs get confused talking about it or equate it with bubbling, but I hope the following description is clear.
Suppose you want to respond to a click on any A tag on the page, even if the set of A tags changes over time. In particular, you don't want to visit every A tag and add an event listener. So, taking advantage of bubbling, you bind a single event handler to the BODY, and from this handler you look at event.target to see if an A was clicked, and if so, which one. Be careful, though, because event.target may be the SPAN! You need to not just check if the event's target is an A tag, but also walk up the DOM tree in a simple simulation of bubbling.
This is event delegation. The BODY element is the delegate that handles events on behalf of the A tags. Conceptually, we'd like to think of the event handler as being on the A tags, so we create that illusion as much as we can. To that end, the final step in event delegation (at least in jQuery and Meteor) is to set event.currentTarget to the A tag. Further code that handles the event then sees an A tag as currentTarget and a SPAN tag as target. The BODY element is not really important, so it is nowhere to be found.
我有一个 div(标签),里面有 3 个跨度,像这样:
<div class="chat-tabs">
<div class="chat-tabs-cont">
<div id="chat-tab-1" class="chat-tab chat-tab-sel">
<span class="chat-tab-n">1</span>
<span class="chat-tab-t">Tab text 1</span>
<span class="chat-tab-c">11:00</span>
</div>
<div id="chat-tab-2" class="chat-tab">
<span class="chat-tab-n">2</span>
<span class="chat-tab-t">Tab text 2</span>
<span class="chat-tab-c">11:30</span>
</div>
</div>
</div>
这些是选项卡,所以当我单击一个选项卡时,我在 Meteor 中有一个单击事件,为新选项卡提供 class 的 chat-tab-sel
并从中删除此 class旧选项卡(标准选项卡行为)。
我的问题是,根据用户点击的位置,我的 event.target
并不总是 parent div chat-tab
,而是 child span
。我需要 add/remove classes 到 parent div
.
我认为如果 parent 有 display: block
它可能会起作用,但在这种情况下我需要它是 display: flex
因为在 [=32 上有灵活的宽度是有意义的=]s.
所以:是否可以确保当用户点击 child 时 parent div 是有针对性的?
事件气泡。这意味着您可以监听父级上的事件。在事件侦听器中,this
绑定到您将事件侦听器绑定到的元素。所以我们可以监听该元素内的任何点击,然后将当前活动选项卡设置为非活动状态,并将单击的选项卡设置为活动状态。
具体不确定 Meteor,但这就是我使用 vanilla JavaScript.
完成此操作的方式var tabs = document.querySelectorAll('.chat-tab');
for(var i in Object.keys(tabs)) tabs[i].onclick = function() {
document.querySelector('.chat-tab.chat-tab-sel').className = 'chat-tab';
this.className += ' chat-tab-sel'
}
.chat-tab-sel {
border: 1px solid #012450;
}
<div class="chat-tabs">
<div class="chat-tabs-cont">
<div id="chat-tab-1" class="chat-tab chat-tab-sel">
<span class="chat-tab-n">1</span>
<span class="chat-tab-t">Tab text 1</span>
<span class="chat-tab-c">11:00</span>
</div>
<div id="chat-tab-2" class="chat-tab">
<span class="chat-tab-n">2</span>
<span class="chat-tab-t">Tab text 2</span>
<span class="chat-tab-c">11:30</span>
</div>
</div>
</div>
如果您将普通的 Meteor 事件处理程序与@Brian Shamblen 的提示结合使用,它应该可以正常工作。
Template.myTemplate.events({
'click .chatTab': function(ev){
$(".chat-tab").removeClass("chat-tab-sel"); // remove from all
$(ev.target).closest(".chat-tab").addClass("chat-tab-sel"); // set the one you're on
}
});
基于 Tiny Giant 对事件冒泡的回答,这里是在 meteor 中执行此操作:
Template.theTemplate.events({
'click .chat-tab': function(ev) {
$('.chat-tab').removeClass('chat-tab-sel');
$(ev.currentTarget).addClass('chat-tab-sel');
}
});
这是一篇有趣的 info.meteor.com 博文,其中对此进行了一些详细介绍:
Browser events: bubbling, capturing, and delegation
Suppose you have this HTML structure:
<body>
<p>
<a><span>Hello</span></a>
</p>
</body>
Event delegation is not a browser feature, but a popular technique built into libraries like jQuery. Many blogs get confused talking about it or equate it with bubbling, but I hope the following description is clear.
Suppose you want to respond to a click on any A tag on the page, even if the set of A tags changes over time. In particular, you don't want to visit every A tag and add an event listener. So, taking advantage of bubbling, you bind a single event handler to the BODY, and from this handler you look at event.target to see if an A was clicked, and if so, which one. Be careful, though, because event.target may be the SPAN! You need to not just check if the event's target is an A tag, but also walk up the DOM tree in a simple simulation of bubbling.
This is event delegation. The BODY element is the delegate that handles events on behalf of the A tags. Conceptually, we'd like to think of the event handler as being on the A tags, so we create that illusion as much as we can. To that end, the final step in event delegation (at least in jQuery and Meteor) is to set event.currentTarget to the A tag. Further code that handles the event then sees an A tag as currentTarget and a SPAN tag as target. The BODY element is not really important, so it is nowhere to be found.