web-dev-qa-db-fra.com

Objets JavaScript: 'addEventListener n'est pas une fonction'

Je crée un tableau d'objets JavaScript appelés éléments et les parcourt afin de les dessiner sur un canevas et d'y brancher quelques gestionnaires d'événements. Cependant, je reçois une erreur indiquant que 

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

Voici le 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;
}

Pourquoi ne puis-je pas associer un gestionnaire d'événements à chaque élément?

6
kformeck

Votre erreur spécifique:

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

c'est parce que elements[i].addEventListener est undefined et n'est donc pas une fonction. La raison pour laquelle il est undefined est que votre tableau elements contient des objets Javascript normaux. Ces objets n'ont pas de méthode .addEventListener(). C'est une méthode sur les objets DOM qui est une EventTarget , pas des objets Javascript normaux (à moins que vous ne créiez votre propre méthode appelée addEventListener et que vous l'ajoutiez à vos objets Javascript).

Étant donné que je ne vois pas de tableau correspondant d'éléments DOM dans votre code, il semble que vous tentiez d'associer eventListeners aux rectangles dessinés sur votre canevas, ce que vous ne pouvez pas faire de cette manière. Les choses que vous avez dessinées sur un objet Canvas ressemblent à une bitmap. Il ne conserve aucune connaissance des objets que vous avez dessinés, à l'exception des pixels obtenus. Vous dessinez dessus et le résultat est des pixels sur le canevas, et non un ensemble persistant d'objets tels que des objets DOM. Si vous souhaitez effectuer plus tard des tests de frappe par rapport aux éléments que vous avez dessinés sur le canevas, vous devez alors placer un événement eventListener sur l'objet de canevas lui-même pour obtenir l'événement d'entrée. Lorsque l'événement se déclenche sur votre écouteur de zone de dessin, vous pouvez effectuer votre propre test de hit en fonction des données de ce que vous avez placé.

10
jfriend00

Vous créez un tableau d'objets javascript de base. Qui n'ont pas la méthode addEventListener qui ne sont utilisées que dans les objets EventTarget .

Regardez cette question similaire pour une idée sur la façon de faire ce que vous voulez faire.

1
Illyism

Vous essayez d'attacher EventListener() à des objets qui ne prennent pas en charge les événements.

De les docs :

La cible de l'événement peut être une Element dans un document, la Document lui-même, un Window ou tout autre objet prenant en charge des événements (tels que XMLHttpRequest).

Ce que vous appelez elements ne correspond à aucun des critères ci-dessus.

0
PM 77-1