Reputation: 769
I have function like this:
$(document).ready(function () {
$("*").click(function () {
alert($(this).attr('id').toString());
});
});
And on Page i have something like this:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<script language="javascript" src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<div id="div1">Some stuff
<div id="div2">Some other stuff
<asp:Button ID="Button1" runat="server" Text="Button" />
<div id="div3">More stuff
<asp:Button ID="Button2" runat="server" Text="Button" />
</div>
</div>
</div>
If i click something it works fine, but it alerts me three times(or more). For example: I click button2. Alertbox appears with button2.id, then with div3.id, div2.id etc. It shows me all id's under that button. If i try to store this id to variable like this:
var storedId = $(this).attr('id').toString();
it stores the last one.That means i get the id of form1.
How can i get the first id? The id of clicked button or clicked label or whatever i have on my page.
Upvotes: 3
Views: 1242
Reputation: 707956
You need to stop event propagation up the DOM tree so parent items don't see the same event. In jQuery, you can do that with e.stopPropagation()
:
$("*").click(function(e) {
alert($(this).attr('id').toString());
e.stopPropagation();
});
FYI, this is a really inefficient way to do this. You would do it better like this with a single event handler that takes advantage of event bubbling and catches the bubbled click events at the document and examines them in just this one place:
$(document).click(function(e) {
alert(e.target.id);
});
Upvotes: 5
Reputation: 82317
Others have answered that you can screen the rest of the "useless" events out by stopping their propagation. +1, for this situation, I think that is entirely correct. However, I think there is a better approach that you can use other than using the * selector.
$("*").click()
uses the All Selector ("*"). When the all selector (*) is used it attaches that event to every element on the page. Using this approach is not ideal (performance hits, bad practice, overly complex) unless you have a reason to handle a click event for every element on the page (possible, but highly unlikely).
A better approach would be to just assign click events to individual elements (kind of the web standard).
So, if given this scenario
<asp:Button ID="Button1" runat="server" Text="Button" />
<div id="div3">More stuff
<asp:Button ID="Button2" runat="server" Text="Button" />
</div>
</div>
use two event handlers (one for each button)
$(document).ready(function () {
$("#Button1").click(function () {
alert($(this).attr('id').toString());//note that this.id will also work
});
$("#Button2").click(function () {
alert($(this).attr('id').toString());
});
});
Although this approach requires more event definitions, it makes up for that by easily providing unique event handling per element, more readable code, and better separation of concerns.
Upvotes: 0
Reputation: 700690
The event bubbles, so it will show the id of each element that it bubbles through.
Use the stopPropagation
method to keep the event from bubbling:
$(document).ready(function () {
$("*").click(function (e) {
e.stopPropagation();
alert($(this).attr('id').toString());
});
});
Upvotes: 2
Reputation: 145458
You should stop event propagation with stopPropagation()
:
$("*").click(function(e) {
alert($(this).attr("id").toString());
e.stopPropagation();
});
Method prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
Upvotes: 3