admin管理员组

文章数量:1299763

I create an array of JavaScript objects called elements and loop through it in order to draw every one on a canvas as well as hooking up a few event handlers to it. However, I get an error stating that

'Uncaught TypeError: elements[i].addEventListener is not a function'

Here is the code:

$(document).ready(onDocumentReady);
function onDocumentReady() {
    var COLOR_NORMAL = '#005A84';
    var COLOR_SELECTED = '#00F2F2';
    var COLOR_MOUSEOVER = '#5BA621';

    var canvas = document.getElementById("mapCanvas");
    var context = canvas.getContext('2d');
    var data = @Html.Raw(Json.Encode(Model.DiePrintList));
    var elem =
        canvas,
        left = elem.offsetLeft,
        top = elem.offsetTop,
        context = elem.getContext('2d'),
        elements = [];
    for (var i = 0; i < data.length; i++) {
        elements.push({
            color: '#0489B1',
            width: 15,
            height: 15,
            row: data[i].Row,
            col: data[i].Col,
            top: data[i].Row * 20,
            left: data[i].Col * 20
        });
    }
    for (var i = 0; i < elements.length; i++) {
        elements[i].addEventListener('click', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_SELECTED;
            drawElement(context, hitElement);
        }, false);
        elements[i].addEventListener('mouseover', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_MOUSEOVER;
            drawElement(context, hitElement);
        }, false);
        elements[i].addEventListener('mouseout', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_SELECTED;
            drawElement(context, hitElement);
        }, false);
        drawElement(context, elements[i]);
    }
}
function drawElement(context, element) {
    context.fillStyle = element.color;
    context.fillRect(element.left, element.top, element.width, element.height);
}
function getHitElement(elements, x, y) {
    var hitElement;
    for (var i = 0; i < elements.length; i++) {
        if (y > elements[i].top && y < elements[i].top + elements[i].height && 
            x > elements[i].left && x < elements[i].left + elements[i].width) {
            hitElement = elements[i];
        }
    }
    return hitElement;
}

Why is it that I cannot hook up an event handler to each individual element?

I create an array of JavaScript objects called elements and loop through it in order to draw every one on a canvas as well as hooking up a few event handlers to it. However, I get an error stating that

'Uncaught TypeError: elements[i].addEventListener is not a function'

Here is the code:

$(document).ready(onDocumentReady);
function onDocumentReady() {
    var COLOR_NORMAL = '#005A84';
    var COLOR_SELECTED = '#00F2F2';
    var COLOR_MOUSEOVER = '#5BA621';

    var canvas = document.getElementById("mapCanvas");
    var context = canvas.getContext('2d');
    var data = @Html.Raw(Json.Encode(Model.DiePrintList));
    var elem =
        canvas,
        left = elem.offsetLeft,
        top = elem.offsetTop,
        context = elem.getContext('2d'),
        elements = [];
    for (var i = 0; i < data.length; i++) {
        elements.push({
            color: '#0489B1',
            width: 15,
            height: 15,
            row: data[i].Row,
            col: data[i].Col,
            top: data[i].Row * 20,
            left: data[i].Col * 20
        });
    }
    for (var i = 0; i < elements.length; i++) {
        elements[i].addEventListener('click', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_SELECTED;
            drawElement(context, hitElement);
        }, false);
        elements[i].addEventListener('mouseover', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_MOUSEOVER;
            drawElement(context, hitElement);
        }, false);
        elements[i].addEventListener('mouseout', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_SELECTED;
            drawElement(context, hitElement);
        }, false);
        drawElement(context, elements[i]);
    }
}
function drawElement(context, element) {
    context.fillStyle = element.color;
    context.fillRect(element.left, element.top, element.width, element.height);
}
function getHitElement(elements, x, y) {
    var hitElement;
    for (var i = 0; i < elements.length; i++) {
        if (y > elements[i].top && y < elements[i].top + elements[i].height && 
            x > elements[i].left && x < elements[i].left + elements[i].width) {
            hitElement = elements[i];
        }
    }
    return hitElement;
}

Why is it that I cannot hook up an event handler to each individual element?

Share Improve this question asked Jun 19, 2015 at 19:56 kformeckkformeck 1,8235 gold badges23 silver badges45 bronze badges 1
  • "anyFunction is not a function" means that anyFunction is not part of the object from where its called. – user1636522 Commented Jun 19, 2015 at 20:00
Add a comment  | 

3 Answers 3

Reset to default 17

Your specific error:

'Uncaught TypeError: elements[i].addEventListener is not a function'

is because elements[i].addEventListener is undefined and thus is not a function. The reason it is undefined is because your elements array contains regular Javascript objects. Those objects do not have a .addEventListener() method. That is a method on DOM objects that are an EventTarget, not regular Javascript objects (unless you make your own method called addEventListener and add it to your Javascript objects).

Since I don't see a corresponding array of DOM elements in your code, it appears like you're trying to attach eventListeners to rectangles you draw on your Canvas which is not something you can do in that way. T'he things you've drawn on a Canvas object are basically like a bitmap. It doesn't retain a knowledge of objects you drew on it other than the resulting pixels. You draw on it and the result is pixels on the canvas, not a persistent set of objects such as DOM objects. If you want to later do hit testing versus things you drew on the canvas, then you'd have to put an eventListener on the canvas object itself to get the input event, keep track yourself of what object you drew where on the canvas and then when the event triggers on your canvas listener, you can do your own hit testing versus that data of what you put where.

You're making an array of basic javascript objects. Which don't have the addEventListener method which are only used in EventTarget objects.

Look at this similar question for an idea on how to do what you want to do

You are trying to attach EventListener() to objects that do not support events.

From the docs:

The event target may be an Element in a document, the Document itself, a Window, or any other object that supports events (such as XMLHttpRequest).

What you call elements does not match any of the above criteria.

本文标签: htmlJavaScript objects 39addEventListener is not a function39Stack Overflow