I have an HTML document with text. What I would like to acplish is that when you click on a div
element, the id
of that div
is shown.
I tried this:
window.onload = function() {
associateIds();
clicked();
}
function associateIds() {
var all = document.getElementsByTagName("*");
var id = -1;
for (var elem = 0; elem < all.length; elem++) {
if (all[elem].tagName == "DIV") {
id++;
all[elem].setAttribute("id", id);
}
}
}
function clicked() {
document.body.onclick = function(evt) {
var evt = window.event || evt; //window.event for IE
if (!evt.target) {
evt.target = evt.srcElement; //extend target property for IE
}
alert(evt.target.id);
}
}
<div>
<h1>MAIN TITLE</h1>
</div>
<div>
<h2>Title</h2>
</div>
<div>
<p>
<strong>Alice</strong> was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it,<i> 'and what is the use of a book,'</i> thought
Alice<i> 'without pictures or conversations?’</i>.
</p>
</div>
<div>
<p>
So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a <strong>White Rabbit</strong> with
pink eyes ran close by her. There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, <i>'Oh dear! Oh dear!
I shall be late!'</i> (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural). But when the <strong>Rabbit</strong> actually took a watch out of its waistcoat-pocket,
and looked at it, and then hurried on, <strong>Alice</strong> started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran
across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.
</p>
</div>
<div>
<p>
Down, down, down. Would the fall never e to an end! <i>'I wonder how many miles I've fallen by this time?' she said aloud. 'I must be getting somewhere near the centre of the earth. Let me see: that would be four thousand miles down, I think—'</i> (for,
you see, <strong>Alice</strong> had learnt several things of this sort in her lessons in the schoolroom, and though this was not a very good opportunity for showing off her knowledge, as there was no one to listen to her, still it was good practice
to say it over)<i> '—yes, that's about the right distance—but then I wonder what Latitude or Longitude I've got to?' </i>(Alice had no idea what Latitude was, or Longitude either, but thought they were nice grand words to say).
<p>
</div>
I have an HTML document with text. What I would like to acplish is that when you click on a div
element, the id
of that div
is shown.
I tried this:
window.onload = function() {
associateIds();
clicked();
}
function associateIds() {
var all = document.getElementsByTagName("*");
var id = -1;
for (var elem = 0; elem < all.length; elem++) {
if (all[elem].tagName == "DIV") {
id++;
all[elem].setAttribute("id", id);
}
}
}
function clicked() {
document.body.onclick = function(evt) {
var evt = window.event || evt; //window.event for IE
if (!evt.target) {
evt.target = evt.srcElement; //extend target property for IE
}
alert(evt.target.id);
}
}
<div>
<h1>MAIN TITLE</h1>
</div>
<div>
<h2>Title</h2>
</div>
<div>
<p>
<strong>Alice</strong> was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it,<i> 'and what is the use of a book,'</i> thought
Alice<i> 'without pictures or conversations?’</i>.
</p>
</div>
<div>
<p>
So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a <strong>White Rabbit</strong> with
pink eyes ran close by her. There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, <i>'Oh dear! Oh dear!
I shall be late!'</i> (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural). But when the <strong>Rabbit</strong> actually took a watch out of its waistcoat-pocket,
and looked at it, and then hurried on, <strong>Alice</strong> started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran
across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.
</p>
</div>
<div>
<p>
Down, down, down. Would the fall never e to an end! <i>'I wonder how many miles I've fallen by this time?' she said aloud. 'I must be getting somewhere near the centre of the earth. Let me see: that would be four thousand miles down, I think—'</i> (for,
you see, <strong>Alice</strong> had learnt several things of this sort in her lessons in the schoolroom, and though this was not a very good opportunity for showing off her knowledge, as there was no one to listen to her, still it was good practice
to say it over)<i> '—yes, that's about the right distance—but then I wonder what Latitude or Longitude I've got to?' </i>(Alice had no idea what Latitude was, or Longitude either, but thought they were nice grand words to say).
<p>
</div>
But when I click on a div, this is what happens:
In my code, the IDs are not assigned statically but by the function associateIds()
. I have verified that the function does its job:
The IDs are there, but they're not shown when you click.
I would prefer to use pure JavaScript, not jQuery.
Why does this happen? How can I fix it?
Share Improve this question edited Sep 19, 2015 at 18:28 Michael Laszlo 12.2k2 gold badges32 silver badges47 bronze badges asked Sep 19, 2015 at 18:02 user5346990user5346990 2- Console log your evt.targets - they have no ids, you have applied ids just to divs.... – sinisake Commented Sep 19, 2015 at 18:11
- just because a parent has id doesn't mean the target does. What is your use case? – charlietfl Commented Sep 19, 2015 at 18:11
6 Answers
Reset to default 6Adding while
loop to get the parent div
.
You have to add parentNode
, because when you click the target isn't the div
that have id
but someone of childs, so you have to add parentNode
and loop up through elements until you get the parent div
that have id
, see following code :
function clicked() {
document.body.onclick = function(evt) {
var evt = window.event || evt; //window.event for IE
if (!evt.target) {
evt.target = evt.srcElement; //extend target property for IE
}
var parent = evt.target.parentNode;
while (parent.tagName != 'DIV') {
parent = parent.parentNode;
}
alert(parent.id);
}
}
Updated fiddle using closest()
Or you can use closest()
like :
function clicked() {
document.body.onclick = function(evt) {
var evt = window.event || evt; //window.event for IE
if (!evt.target) {
evt.target = evt.srcElement; //extend target property for IE
}
var parent = evt.target.closest('div');
alert(parent.id);
}
}
Hope this helps.
evt.target
is the element that was clicked.
In your case you always have an element inside your div (either a p
or an h1
, or an h2
), that's the one you're trying to get the id.
If you replace
alert(evt.target.id);
with
alert(evt.target.parentNode.id);
You'll see that it works, however this is not a bulletproof solution (it assumes parentNode is always the div you're trying to select). In order to grab the id of a div you have to recursively traverse the dom until you find a div, and then grab its Id.
The easiest way to solve this problem is to attach a click handler to each div
. You can do so while you're assigning the ID.
You can assign the same function to be the click handler for each div
. The function can consult this.id
to get the clicked element's id
because this
is the element that was clicked.
In the following snippet, I have simplified your code by iterating over div
elements only instead of all page elements.
window.onload = function() {
associateIdsAndClickHandler();
}
function click(event) {
alert(this.id);
}
function associateIdsAndClickHandler() {
var divs = document.getElementsByTagName('div'),
numDivs = divs.length;
for (var i = 0; i < numDivs; ++i) {
divs[i].id = i;
divs[i].onclick = click;
}
}
<div>
<h1>MAIN TITLE</h1>
</div>
<div>
<h2>Title</h2>
</div>
<div>
<p>
<strong>Alice</strong> was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it,<i> 'and what is the use of a book,'</i> thought
Alice<i> 'without pictures or conversations?’</i>.
</p>
</div>
<div>
<p>
So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a <strong>White Rabbit</strong> with
pink eyes ran close by her. There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, <i>'Oh dear! Oh dear!
I shall be late!'</i> (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural). But when the <strong>Rabbit</strong> actually took a watch out of its waistcoat-pocket,
and looked at it, and then hurried on, <strong>Alice</strong> started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran
across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.
</p>
</div>
<div>
<p>
Down, down, down. Would the fall never e to an end! <i>'I wonder how many miles I've fallen by this time?' she said aloud. 'I must be getting somewhere near the centre of the earth. Let me see: that would be four thousand miles down, I think—'</i> (for,
you see, <strong>Alice</strong> had learnt several things of this sort in her lessons in the schoolroom, and though this was not a very good opportunity for showing off her knowledge, as there was no one to listen to her, still it was good practice
to say it over)<i> '—yes, that's about the right distance—but then I wonder what Latitude or Longitude I've got to?' </i>(Alice had no idea what Latitude was, or Longitude either, but thought they were nice grand words to say).
<p>
</div>
1/ in your code the event target is not necessary the div, but the inner element, (p, or strong for instance). You have to look for the first parent div by iterating on the target parent node
2/ you could use dataset to store data
window.onload = function() {
associateIds();
clicked();
}
function associateIds() {
var all = document.getElementsByTagName("*");
var id = -1;
for (var elem = 0; elem < all.length; elem++) {
if (all[elem].tagName == "DIV") {
id++;
all[elem].dataset.id = id;
}
}
}
function clicked() {
document.body.addEventListener('click', function(evt) {
var evt = window.event || evt; //window.event for IE
if (!evt.target) {
evt.target = evt.srcElement; //extend target property for IE
}
var e = evt.target;
// look for parent div
while (e && e.tagName != 'DIV') {
e = e.parentNode;
}
if (e) {
alert(e.dataset.id);
} else {
alert('not in a div');
}
});
}
<div>
<h1>MAIN TITLE</h1>
</div>
<div>
<h2>Title</h2>
</div>
<div>
<p>
<strong>Alice</strong> was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it,<i> 'and what is the use of a book,'</i> thought
Alice<i> 'without pictures or conversations?’</i>.
</p>
</div>
<div>
<p>
So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a <strong>White Rabbit</strong> with
pink eyes ran close by her. There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, <i>'Oh dear! Oh dear!
I shall be late!'</i> (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural). But when the <strong>Rabbit</strong> actually took a watch out of its waistcoat-pocket,
and looked at it, and then hurried on, <strong>Alice</strong> started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran
across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.
</p>
</div>
<div>
<p>
Down, down, down. Would the fall never e to an end! <i>'I wonder how many miles I've fallen by this time?' she said aloud. 'I must be getting somewhere near the centre of the earth. Let me see: that would be four thousand miles down, I think—'</i> (for,
you see, <strong>Alice</strong> had learnt several things of this sort in her lessons in the schoolroom, and though this was not a very good opportunity for showing off her knowledge, as there was no one to listen to her, still it was good practice
to say it over)<i> '—yes, that's about the right distance—but then I wonder what Latitude or Longitude I've got to?' </i>(Alice had no idea what Latitude was, or Longitude either, but thought they were nice grand words to say).
<p>
</div>
Here's approach that walks up the dom tree either until an ID is encountered or body is reached
document.body.onclick = function (evt) {
var evt = window.event || evt; //window.event for IE
var el = evt.target || evt.srcElement,
id = el.id;
while (!id && el.tagName !== 'BODY') {
el = el.parentNode;
id = el.id;
}
if(typeof id !== 'undefined'){
alert(id);
}
}
DEMO
Zakaria Acharki is right, your current problem is that the target of the event is not the DIV, but one of its children elements (p, b, h1, etc).
So you have to walk up the DOM in order to find the element that you want.
Here's a snippet showing what you could do:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<h1>MAIN TITLE</h1>
</div>
<div>
<h2>Title</h2>
</div>
<div>
<p>
<strong>Alice</strong> was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it,<i> 'and what is the use of a book,'</i> thought
Alice
<i> 'without pictures or conversations?’</i>.
</p>
</div>
<div>
<p>
So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a <strong>White Rabbit</strong> with
pink eyes ran close by her. There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, <i>'Oh dear! Oh dear!
I shall be late!'</i> (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural). But when the <strong>Rabbit</strong> actually took a watch out of its waistcoat-pocket,
and looked at it, and then hurried on, <strong>Alice</strong> started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she
ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.
</p>
</div>
<div>
<p>
Down, down, down. Would the fall never e to an end! <i>'I wonder how many miles I've fallen by this time?'
she said aloud. 'I must be getting somewhere near the centre of the earth. Let me see: that would be four
thousand miles down, I think—'</i> (for, you see, <strong>Alice</strong> had learnt several things of this sort in her lessons in the schoolroom, and though this was not a very good opportunity for showing off her knowledge, as there was no one to
listen to her, still it was good practice to say it over)<i> '—yes, that's about the right distance—but then I wonder what Latitude or Longitude I've got
to?' </i>(Alice had no idea what Latitude was, or Longitude either, but thought they were nice grand words to say).
<p>
</div>
<script type="text/javascript">
window.onload = function() {
associateIds();
clicked();
};
function associateIds() {
var all = document.getElementsByTagName("*");
var id = -1;
for (var elem = 0; elem < all.length; elem++) {
if (all[elem].tagName == "DIV") {
id++;
all[elem].setAttribute("id", id);
}
}
}
function clicked() {
document.body.onclick = function(evt) {
var evt = window.event || evt; //window.event for IE
if (!evt.target) {
evt.target = evt.srcElement; //extend target property for IE
}
var parentDIV = getParent(evt.target, 'DIV');
if (parentDIV) {
alert('clicked on div#' + parentDIV.id);
}
}
}
function getParent(elm, tagName) {
while (elm.tagName != tagName && elm.parentNode != null) {
elm = elm.parentNode;
}
return elm.tagName == tagName ? elm : null;
}
</script>
</body>
</html>
Hope it helps!