javascript - 为什么 jQuery 不能直接操作 SVG 元素的类?

标签 javascript jquery svg

我责怪自己的愚蠢,但我一生都无法理解为什么 jQuery (2.1.4) 不能使用它的类函数直接更改 SVG 元素(或子元素)的类?我正在尝试为 jQuery 制作一个 SVG 操作插件,并且正在测试各种东西以使类可更改(是的,我尝试过常见的 SVG 库;不,我不关心它们) 。我最终选择了当前的版本,它智能地覆盖了原始的 jQuery.addClass() 函数。我检查 jQuery 元素的数组是否包含 SVG 类型节点,如果包含,我使用自定义函数,否则,我将其传递回原始 jQuery 函数。到目前为止这似乎有效。话虽这么说,我的“自定义”函数与 jQuery 函数的代码完全相同,因为我从 GitHub 上的源代码复制了它。那么,如果它适用于我的“自定义”函数,为什么它不能简单地适用于默认的 jQuery 函数呢?

这是我到目前为止的代码。就语法而言,我的代码与我的风格不同,但它实际上与原始 jQuery 代码执行完全相同的操作。

(function ($) {
    var element,
        jQueryFunctions = {
            addClass: $.fn.addClass
        };

    var addClass = function (
        elements,
        value) {
        var proceed = typeof (value) === "string" && value;

        if (!proceed) {
            return this;
        }

        for (var i = 0, j, l = elements.length, element, klasses = (value || "").match(/\S+/g) || [], klass, currentValue, current, finalValue; element = elements[i], i < l; i++) {
            currentValue = element.getAttribute && element.getAttribute("class") || "",
            current = element.nodeType === 1 && (" " + currentValue + " ").replace(/[\t\r\n\f]/g, " ");

            if (!current) {
                return;
            }

            j = 0;

            while (klass = klasses[j++]) {
                if (current.indexOf(" " + klass + " ") < 0) {
                    current += klass + " ";
                }

                finalValue = jQuery.trim(current);

                if (currentValue !== finalValue) {
                    element.setAttribute("class", finalValue);
                }
            }
        }
    };

    var hasSvgNodes = function (
        elements) {
        var returnValue = true;

        for (var i = 0, l = elements.length, element; element = elements[i], i < l; i++) {
            returnValue = returnValue && (element.nodeName === "svg");
        }

        return returnValue;
    };

    $.fn.svg = function () {
        return element = this;
    };

    $.fn.addClass = function (
        value) {
        if (!hasSvgNodes(this)) {
            jQueryFunctions.addClass.apply(this, arguments);
        } else {
            addClass(this, value);
        }

        return this;
    };

    $.fn.svg.test = function () {
        element.addClass("Red");
    };
}(jQuery));

最佳答案

@Alex 是正确的。它不起作用(demo)。它曾经一度存在(例如在 1.1 分支中),但现在不再存在。

原因基本上是因为 SVG 元素和 HTML 元素的 className 属性的类型不同。在 HTML 元素中,它是一个字符串。在 SVG 元素中,它是一个 SVGAnimatedString

addClass() 代码期望它是一个字符串。

var  htmlelem = document.getElementById("htmlelem"),
     svgelem = document.getElementById("svgelem");
    
alert("HTML = "+(typeof htmlelem.className) + ". SVG = "+(typeof svgelem.className));
<svg>
    <rect id="svgelem" width="300" height="150"/>
</svg>
<div id="htmlelem"></div>

您自己的版本之所以有效,是因为您似乎从 jQuery 的旧分支中获取了代码。它绝对不是2.1.4版本的addClass

关于javascript - 为什么 jQuery 不能直接操作 SVG 元素的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32239095/

相关文章:

javascript - 使用 jQuery 中的 child() 访问更深层次的项目

javascript - 函数作用域和变量进/出所述函数

javascript - 使用图像最大宽度并保持高度比以实现响应

javascript - D3 将 x 轴标签定位在矩形内并旋转 90 度

javascript - d3 中堆栈函数和嵌套函数的区别?

javascript - 将 d3 与 URL 查询字符串一起使用

javascript - 以编程方式聚焦时不会出现焦点轮廓?

javascript - 循环: images land on the last field only

jquery - jQuery 中比较两个选择框值的奇怪行为

css - 当应用 CSS 过滤器时,内联 SVG 在 iOS 和 Safari 中消失