Reputation: 1245
I have a the following code, it generate a HTML table using a javascript array:
<HTML lang='en'>
<head>
<style>
table {
border-collapse: collapse;
}
table tr td {
border: 1px solid #000;
padding: 10px;
}
table tr td:hover {
color: red;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
window.addEventListener("load", function(){
var data = ["doge", "cate", "birb", "doggo", "moon", "awkward", "coool", "epic"];
var perrow = 3,
html = "<table><tr>";
for (var i=0; i<data.length; i++) {
html += "<td class=\".cell\" >" + data[i] + "</td>";
var next = i+1;
if (next%perrow==0 && next!=data.length) {
html += "</tr><tr>";
}
}
html += "</tr></table>";
document.getElementById("container").innerHTML = html;
});
</script>
</body>
</HTML>
That works fine. What I would like is for the user to be able to hover over any item in the table and have it log the value of the item of the table to the console.
I have searched for solutions and have only found one which kind of works:
$(document).ready(function(){
$('tr').mouseover(function(){
var valueOfTd = $(this).find('td:first-child').text();
console.log(valueOfTd);
});
});
I have two problems with this solution:
So basically, I would like the user to be able to hover over an item in the table and have the contents output to the console, would like the answer in vanilla JS.
Thanks in advance... :)
Upvotes: 0
Views: 1186
Reputation: 3198
Here's one approach. Run this code after you create the table (it can go right after document.getElementById("container").innerHTML = html;
).
var rows = document.getElementsByTagName('tr');
Array.from(rows).forEach(function(tr) {
tr.addEventListener('mouseover', function(event) {
console.log(event.target.textContent);
});
});
Explanation:
getElementsByTagName()
returns a collection of <TR>
s in the document. (For this, you could also use document.querySelectorAll('tr')
, which lets you use jQuery-like CSS selectors to find elements.)Array.from
turns the collection returned by the previous call into a regular JS Array, allowing us to call forEach
on it.addEventListener
to attach a callback function that fires when a <TR>
is hovered over. This is vanilla JS event binding.event
parameter inside the callback contains information about the mouseover event. event.target
. This gives us the <TD>
that the user's cursor is over. This part is a bit subtle, but basically, you can attach listeners to a parent element (the <TR>
s), and the listener will get called when a child element (the <TD>
) is moused over. You don't have to actually add listeners to every cell individually. Search "event bubbling" for a full explanation of how this works.)textContent
property of the <TD>
gives the text inside the cell. This is a standard property of the DOM Node API.Upvotes: 1
Reputation: 381
You could use the following method
function setListeners() {
let tds = document.querySelectorAll('td');
tds.forEach((td) => {
td.addEventListener('mouseover', (e) => {
console.log(e.target.innerHTML);
});
})
}
and would call this method after setting container's innerHTML
document.getElementById("container").innerHTML = html;
setListeners();
Upvotes: 0
Reputation: 599
Try this.
$(document).ready(function() {
$("#container table").on('mouseenter', 'tr', function () {
var tdVal = $(this).children('td').text();
console.log(tdVal);
}
});
Upvotes: 0
Reputation: 896
the problem probably is because when the event handler is bind the table doesn't exists.
You should use a delegated event handler
with jQuery:
$('#container').on('mouseover', 'tr', function(){
var valueOfTd = $(this).find('td:first-child').text();
console.log(valueOfTd);
});
with plain javascript:
var container = document.getElementById('container');
container.addEventListener('mouseover', function(event) {
var target = event.target.closest('tr');
if (! target) return;
var valueOfTd = target.querySelector('td:first-child').innerText;
console.log(valueOfTd);
});
Upvotes: 1