Search code examples
javascripthtmldomgetattribute

What is the cause of this error I was getting?


I'm using JavaScript to populate an HTML page with content. One of those pieces of content is a button/link. The content is generated dynamically, and when the user presses the button I will need to acquire some information that has been embedded (as an attribute) in the button itself.

Here's the general code:

var newCell = newRow.insertCell();
var button = document.createElement("input");
button.type = "image";
button.src = "/images/image.png";
button.setAttribute("customData", "dynamically generated data");
button.setAttribute("onclick", "CustomFunction(this);");
newCell.appendChild(button);


CustomFunction(obj) {
      var data = obj.getAttribute("customData"));
};

When I get into the function (by pressing the button), the browser throws an error along the lines of cannot getAttribute of null object.

But it seems to work if I get rid of button.src.

I've already found a way around this, but I would like to know what causes this issue?

EDIT: Here's the actual code:

var newCell = newRow.insertCell();
var button = document.createElement("input");
button.type = "image";
button.src = "/images/image.png";
button.setAttribute("customData", "dynamically generated data (JSON format)");
button.setAttribute("onclick", "CustomFunction(this);");
newCell.appendChild(button);

function CustomFunction(obj) {
    buttonObj = obj.querySelector('input[type=image][customData]');
    var dataObj = JSON.parse(buttonObj.getAttribute("customData"));
};

Solution

  • The problem is this line:

    buttonObj = obj.querySelector('input[type=image][customData]');
    

    querySelector searches the descendants of the given element for an element that matches the selector. But the element you're looking for is the same as obj, not one of its descendants.

    Your code will work if you put the click handler on the cell rather than the button.

    newCell.setAttribute("onclick", "CustomFunction(this);");
    

    or

    newCell.addEventListener("click", function() {CustomFunction(this);});
    

    Or you can simply make buttonObj the argument to CustomFunction(), instead of using querySelector().