web-dev-qa-db-ja.com

JavaScriptオブジェクト: 'addEventListener is not a function'

要素と呼ばれるJavaScriptオブジェクトの配列を作成し、それをループして、キャンバスにすべてを描画し、それにいくつかのイベントハンドラーを接続します。ただし、次のエラーが表示されます

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

これがコードです:

$(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;
}

イベントハンドラーを個々の要素にフックできないのはなぜですか?

8
kformeck

あなたの特定のエラー:

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

_elements[i].addEventListener_はundefinedであり、関数ではないためです。 undefinedである理由は、elements配列に通常のJavascriptオブジェクトが含まれているためです。これらのオブジェクトには.addEventListener()メソッドがありません。これは EventTarget であるDOMオブジェクトのメソッドであり、通常のJavaScriptオブジェクトではありません(addEventListenerという独自のメソッドを作成してJavascriptオブジェクトに追加しない限り) 。

コードに対応するDOM要素の配列が表示されないため、Canvasで描画した四角形にeventListenersをアタッチしようとしているように見えますが、この方法ではできません。 Canvasオブジェクトに描画したものは、基本的にビットマップのようなものです。結果として得られるピクセル以外に、描画したオブジェクトに関する知識は保持されません。そこに描画すると、結果はキャンバス上のピクセルであり、DOMオブジェクトなどの永続的なオブジェクトのセットではありません。後でキャンバス上で描画したものに対してヒットテストを実行する場合は、canvasオブジェクト自体にeventListenerを配置して入力イベントを取得し、キャンバス上のどこに描画したオブジェクトを追跡する必要があります。キャンバスリスナーでイベントがトリガーされると、配置したデータのデータと比較して、独自のヒットテストを実行できます。

12
jfriend00

基本的なJavaScriptオブジェクトの配列を作成しています。 EventTarget オブジェクトでのみ使用されるaddEventListenerメソッドがありません。

これに似た question を見て、やりたいことを行う方法についてのアイデアを見つけてください

1
Illyism

イベントをサポートしないオブジェクトにEventListener()をアタッチしようとしています。

the docs から:

イベントターゲットは、ドキュメント内のElementDocument自体、Window、またはイベントをサポートするその他のオブジェクト(XMLHttpRequestなど)です。 。

elementsと呼ばれるものは、上記の基準のいずれにも一致しません。

0
PM 77-1