Reputation: 778
UPDATED
I think I may have inadvertently made the question confusing. This is an update that is more specific with updated code based on comments and answer I have been given so far. Thank you to everyone that has taken the time to comment and answer.
How can I get the ID of a <div>
with the class of .button
when I have a click listener for .button
. If .button
or any of its children are clicked, it should return the ID for that particular div
with the class of .button
.
This is what I have so far: New JSFiddle
HTML
<div class="row">
<div id="b1" class="button">
<h2>Button 1</h2>
</div>
<div id="b2" class="button">
<h2>Button 2</h2>
</div>
<div id="b3" class="button">
<h2>Button 3</h2>
</div>
</div>
jQuery
var selected = "";
$('.button').on('click', function(e) {
selected = e.target.id;
$('.button').css('backgroundColor', '#becde5');
$('#' + selected).css('backgroundColor', '#3b71c6');
$('#selected').html(selected);
});
This is almost correct but does not propagate, if I click on a <h2>
the function does not work. However if I click on the .button
div itself it works.
Initial Question
I am trying to create a general function that can identify what child was selected from its parents click listener. The child may have its own children that would all be considered part of the same element so that if any of these children where selected they should also elicit the same response from the click listener.
This is an example of what I have working so far: JSFiddle
HTML consisting of three buttons that all have one child <h2>
tag and share the <div class="row">
as their parent.
<div class="row">
<div class="b1 button">
<h2 class="b1">Button 1</h2>
</div>
<div class="b2 button">
<h2 class="b2">Button 2</h2>
</div>
<div class="b3 button">
<h2 class="b3">Button 3</h2>
</div>
</div>
jQuery that listens for a click on <div class="row">
. It retrieves the first class name of the clicked element and stores it in a variable. The elicited response in this case is a change of the CSS style background-color
though this is arbitrary and would change depending on the use of the function.
var selected = "";
$('.row').on('click', function(e) {
selected = e.target.className.split(" ")[0];
$('.b1, .b2, .b3').css('backgroundColor', '#becde5');
$("." + selected).css('backgroundColor', '#3b71c6');
$('#selected').html(selected);
});
The fact that I am adding a lot of classes to elements purely to identify them on a click seems like it would not scale very well and is generally a bad approach. This method also means that I would always have to put the class name that identifies what element was selected at the beginning of its HTML class
attribute. This could potentially clash with other functions using the same method.
Is there a better way to identify what child element was selected from its parents click listener, where a child may have other children that also require the same response from the listener?
Upvotes: 2
Views: 3107
Reputation: 33943
EDIT based on the edited question:
I think that what you really want is the id
of the element that triggered the event.
But by using e.target
you have the target element... which is not necessarily the element that triggered the event.
See in this updated Fiddle.
So simply use $(this)
as the selector to retrieve the id... Using .attr("id")
.
;)
Answer to the initial question:
To determine what can be "selected", I used a "clickable" class.
To avoid using id
or class
as an identifier to determine what has been clicked,
a data
attribute can be usefull.
I used data-id
... But you can use whatever you want, like: data-selected
or data-target
, and assign whatever value to it.
In the below code, I made two exactly identical rows, except their data-id
value.
var selected = "";
$('.clickable').on('click', function(e) {
e.stopPropagation(); // To prevent bubbling.
// Reset all bg colors
$('.button').css('backgroundColor', 'initial');
$('.row').css('backgroundColor', 'initial');
// Find exactly what was clicked
if ($(this).hasClass("row")) {
var row = $(this).data("id");
selected = row + " (whole)";
}
if ($(this).hasClass("button")) {
// Find in which row
var row = $(this).closest(".row").data("id");
var btn = $(this).data("id");
selected = btn + " in " + row;
}
// Pale all buttons
$('.button').css('backgroundColor', '#becde5');
// Change bg color of the selected element
$(this).css('backgroundColor', '#3b71c6');
$('#selected').html(selected);
});
.row {
display: table;
width: 100%;
color: white;
border-spacing: 20px;
}
.button {
display: table-cell;
border-radius: 12px;
background-color: #6fa1f2;
text-align: center;
}
#selected {
font-size: 30px;
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>Selected : <span id="selected">no selection</span></span><br>
<div class="row clickable" data-id="row1">
<div class="button clickable" data-id="btn1">
<h2>Button 1</h2>
</div>
<div class="button clickable" data-id="btn2">
<h2>Button 2</h2>
</div>
<div class="button clickable" data-id="btn3">
<h2>Button 3</h2>
</div>
</div>
<br>
<div class="row clickable" data-id="row2">
<div class="button clickable" data-id="btn1">
<h2>Button 1</h2>
</div>
<div class="button clickable" data-id="btn2">
<h2>Button 2</h2>
</div>
<div class="button clickable" data-id="btn3">
<h2>Button 3</h2>
</div>
</div>
Upvotes: 3
Reputation: 7201
If you avoid giving an identifier (classes, IDs, etc) you'd need to do some manual checking for tag type to see what you clicked on (so basically, an identifier as well)
Here's an example, and not very memory efficient method jsfiddle example
$('.row, .row *').on('click', function(e) {
e.stopPropagation()
$('.button').removeClass('active')
$('.button').css('backgroundColor', '#becde5');
$(this).toggleClass('active')
$('#selected').html(e.target.tagName + ': ' + e.target.className);
});
If you bind a click to div.row and clicked the h2 tag inside the button, and want to manipulate the h2 tag, you could check its tagName- but that less scalable than your OP.
Upvotes: 0
Reputation: 2542
no need to id the subject, since it was the one clicked, i.e. e.target
which with jQuery you cant select like $(e.target)
without any trouble
then you need .closest('.button')
to search up to the parent .button
(if any)
$('.row').on('click', function(e) {
$('.row > .button').css('backgroundColor', '#becde5');
$(e.target).closest('.button').css('backgroundColor', '#3b71c6');
console.log($(e.target).html());
});
.button {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="row">
<div class="button">
<h2>Button 1</h2>
</div>
<div class="button">
<h2>Button 2</h2>
</div>
<div class="button">
<h2>Button 3</h2>
</div>
</div>
Upvotes: 0