Javascript:DOM 元素和对象之间的区别/"Undefined Is Not A Function"

Javascript: Difference Between DOM elements and Objects/"Undefined Is Not A Function"

在尝试解决这个问题并阅读文档几个小时后,我将放弃这一点。我来自 C/C++ 背景,试图学习 Javascript,我对 DOM 元素和对象之间的区别感到有点困惑。我以为我理解了,但是当我在对象上调用某些函数时,比如“.addEventListener()”,我得到了著名的 "Undefined is not a function" 错误,以及其他有趣的事情。所以这是使用 SVG.js 对同一件事进行的两次尝试。到目前为止,我基本上只是想为我在 SVG canvas 中生成的每个形状添加一个事件侦听器,这样当单击任何形状时,它会独立于所有其他形状改变颜色。

一个在添加事件侦听器行上给了我 "Undefined...",我用第二个版本解决了这个问题,但现在我在函数内部的唯一声明中遇到了 "Undefined..." 错误。

您能否阐明 DOM 元素和对象之间的区别,然后帮助我理解为什么 "Undefined is not a function" 错误会在我的第二个示例中弹出?谢谢。

版本 1:canvas.get() returns 一个对象,我生成的形状之一,调用 .addEventListener() 时出现错误

function changeColor(e) {
    this.fill({color: currentColor});
}
//add event listeners for every element of SVG
var it;
for (it=3; it<=18; it++){
    var canvasName = canvas.get(it);
    canvasName.addEventListener("click", changeColor);
}

版本 2:事件侦听器现在被添加到 DOM 元素并且 "Undefined is not a function" 错误出现在函数内部的声明中(第 2 行)

function changeColor(e) {
    this.fill({color: currentColor});
}
//add event listeners for every element of SVG
var it;
for (it=3; it<=18; it++){
    //get string to search for id in DOM
    var idName = "SvgjsRect" + (1006+it);
    var box = document.getElementById(idName);
    box.addEventListener("click", changeColor);
}

我的最终版本。我意识到他们基本上放弃了所有原生的 DOM 功能,所以我使用了他们的事件绑定方法。

var changeColor = function() {
        this.fill({color: currentColor});
    }
    //add event listeners for every element of SVG
    var it;
    for (it=3; it<=18; it++){
        var box = canvas.get(it);
        box.on('click', changeColor);
    }

浏览了 svg.js 的文档后,它似乎根本没有公开底层的 DOM 元素。没有 return 底层 DOM 对象的方法,也没有任何指向它的属性。

svg.js shapes 对象是底层 DOM 对象的包装器。 DOM 和 DOM 元素最终在 C/C++ 中实现并作为对象暴露给 javascript。然而,它们不是普通对象,因为它们没有在 javascript 中实现。例如,在大多数实现中 DOM 对象没有构造函数。

基本上,在 C++ 术语中,svg.js 形状和 DOM 元素之间的关系是这样的:

class DOMElement {
    /* DOM methods like .addEventListener() */
}

class shape { // from svg.js
    private DOMElement element; // you have no access to this

    /* svg.js shape methods such as .fill() */
}

您发现的一种变通方法是使用 DOM API 获取 DOM 对象 (document.getElementById)。但是你试图在 DOM 对象上调用 svg.js 方法,这当然会失败。

因此,对代码版本 2 的修复是使用 DOM APIs 设置填充:

function changeColor(e) {
    .setAttribute('fill',currentColor);
}

幸运的是,svg.js 库还提供了事件绑定方法,因此您无需使用 DOM API 来添加事件侦听器。因此,另一种解决方案是将 .addEventListener() 替换为:

for (it=3; it<=18; it++){
    var canvasName = canvas.get(it);
    canvasName.click(changeColor);
}

但是,请注意 svg.js 事件侦听器是非标准的,因为它不会将事件对象作为参数传递。所以如果你要这样做,你不应该有那个 (e) 论点。如果需要用(e)那么就需要用上面的DOMAPI