简体   繁体   中英

Get row and cell value from dynamically generated table

I am trying to get the row and cell from a dynamically generated table onClick function. I am getting undefined currently.

xmlTitles = xmlDoc.getElementsByTagName("title");
                document.getElementById('playlist').innerHTML = "Playlist (" + xmlTitles.length + " videos)";
                document.getElementById('table').cellSpacing = "5px";
                for (var i = 0; i < xmlTitles.length; i++)
                {
                    tr = document.createElement('tr');
                    tr.style.height = "100px";
                    titles[i] = xmlDoc.getElementsByTagName("title")[i].childNodes[0].nodeValue;
                    image[i] = xmlDoc.getElementsByTagName("image")[i].childNodes[0].nodeValue;
                    filename[i] = xmlDoc.getElementsByTagName("filename")[i].childNodes[0].nodeValue;
                    td2 = document.createElement('td');
                    var _image = iPath + image[i];
                    td2.innerHTML = "<a href='javascript:callVideo(this);'><img src='" + _image + "'/></a>";
                    td2.style.verticalAlign = "top";
                    tr.appendChild(td2);
                    td1 = document.createElement('td');
                    var _title = titles[i];
                    td1.appendChild(document.createTextNode(_title));
                    td1.style.verticalAlign = "top";
                    td1.style.width = "200px";
                    td1.style.height = "100px";
                    td1.style.color = "#0000ff";
                    td1.style.fontFamily = "arial";
                    tr.appendChild(td1);
                    document.getElementById('table').appendChild(tr);
                }
            }

This is the function called:

function callVideo(x)
            {
                console.log("Cell index: " + x.cellIndex);
}

Thanks.

I think the issue you are having is the context of your callVideo function. When you build up the dynamic table, you create an anchor tag inside td2 and then put the event handler on the a tags href, passing in this. I would suspect, that x in callVideo is not the TD element at all, but the anchor tag (a tag) and since a tags have no cellIndex, it will be undefined. Add a console.log(x) into callVideo and establish exactly what x is. If I am correct, the x.parentNode should get you the TD tag

function callVideo(x)
{
    console.log(x); //Establish what x is
    console.log("Cell index: " + x.parentNode.cellIndex);
}

EDIT In response to comment.

OK so you're having issues establishing the context of the eventHandler. I would change the way you are setting it up, as it not really best practice. An <a> is an anchor/link, and running a function on click is changing its default behaviour, which means you have it add things like javascript(void) or href="#" and return false or e.preventDefault() just to stop it from doing what is suppose to do. All not best practice. Why not just add a click handler to the img, or to the whole cell. eg (I removed the style stuff for clarity, I think that should be in CSS not Javascript too by the way)

xmlTitles = xmlDoc.getElementsByTagName("title");
document.getElementById('playlist').innerHTML = "Playlist (" + xmlTitles.length + " videos)";
document.getElementById('table').cellSpacing = "5px";
for (var i = 0; i < xmlTitles.length; i++)
{
    tr = document.createElement('tr');  
    titles[i] = xmlDoc.getElementsByTagName("title")[i].childNodes[0].nodeValue;
    image[i] = xmlDoc.getElementsByTagName("image")[i].childNodes[0].nodeValue;
    filename[i] = xmlDoc.getElementsByTagName("filename")[i].childNodes[0].nodeValue;
    td2 = document.createElement('td');
    //change here
    var imgEle = document.createElement('img')
    imgEle.src = iPath + image[i];
    imgEle.addEventListener('click', callVideo);
    td2.appendChild(imgEle);

    tr.appendChild(td2);
    td1 = document.createElement('td');
    var _title = titles[i];
    td1.appendChild(document.createTextNode(_title));
    tr.appendChild(td1);
    document.getElementById('table').appendChild(tr);
}

function callVideo()
{
    //'this' will be the img itself
    //so this.parentNode will be the cell (TD)
    console.log(this.parentNode.cellIndex);
    //this.parentNode.parentNode will be the row (TR)
    console.log(this.parentNode.parentNode.rowIndex);
}

OH and by the way, all the cells will return 0 as that is their index, remember Javascript indexes start from 0 (ie 0 is the first one, 1 is the second one etc). So to be honest, I'm not sure why you need the cellIndex, as it will always be 0 (ie the first cell) as you already know its in the first cell, because your code created it. Although if this is just a snippet from larger code, and you have images in other cells then it would make sense.

two changes need to make, given your dynamic generation of DOM is correct.

  1. change <a href="javascript:callVideo(this)">...</a> to <a href="javascript:void(0);" onclick="callVideo(this)">...</a> <a href="javascript:void(0);" onclick="callVideo(this)">...</a> , to make it an event handler . Otherwise because the execution of the function via href is in global context, this will be effectively the global object which is window . Therefore your function will receive window as its parameter which is wrong

  2. change the body of your callVideo function to OJay's solution

    \nfunction callVideo(x) \n{ \n   console.log(x);  //Establish what x is \n   console.log("Cell index: " + x.parentNode.cellIndex); \n}  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM