You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS创建的SVG菜单文本在DOM中存在但无法显示的问题求助

JS创建的SVG菜单文本在DOM中存在但无法显示的问题求助

大家好,我碰到个头疼的问题,想请教下各位大佬。我写了一段JS代码,创建了一个带有左、中、右三个手柄的滑块,点击中间的菱形手柄时会弹出一个菜单框,打算通过遍历两个数组来填充菜单内容。

现在的情况是,用Firefox 138.0 64位版本的F12开发者工具查看,能看到这些菜单的文本元素已经在DOM里创建好了,内容也是正确的,但页面上就是看不到它们。而且在检查器里选中这些文本行的时候,正常情况下应该会显示选中元素的边界框,但这些文本元素完全没有这个框。我对比了其他能正常显示的文本元素,语法看起来是一样的,实在找不到问题出在哪。

以下是我的代码:

var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
const control_W = 550; //width of slider
const control_H = 350; //Height of slider
const left_padding = 75;
const right_padding = 75;
const top_padding = 25;
const bottom_padding = 25;
const pillRad = 10;
const pillOpacity = 50;
const diamondSide = Math.sqrt(2 * (Math.pow(pillRad, 2))); //make the diamond the same height as the circle handles (pythagorus)
const labelOffset = 75;
const PDDheight = 120;
const PDDwidth = 75;
const PDDrad = 2;

svg.setAttribute("id", "sliderControl");
svg.setAttribute("overflow", "visible");
svg.setAttribute("viewBox", "0 0 " + control_W + " " + control_H);
svg.setAttribute("width", control_W);
svg.setAttribute("height", control_H);
svg.setAttribute("onload", "makeDraggable(evt)");

var svgNS = svg.namespaceURI;

var slider = document.createElementNS(svgNS, 'path');
slider.setAttributeNS(null, "d", "M " + left_padding + "," + (top_padding + (control_H / 2)) + " H " + (control_W - right_padding));
slider.setAttribute("id", "slider");
slider.setAttribute("stroke", "silver");
slider.setAttribute("stroke-width", "5");
slider.setAttribute("opacity", "1");
slider.setAttribute("fill", "none");
svg.appendChild(slider);

const startPill = document.createElementNS(svgNS, "circle");
startPill.setAttribute("class", "draggable");
startPill.setAttribute("id", "startPill");
startPill.setAttribute("cx", left_padding);
startPill.setAttribute("cy", (top_padding + (control_H / 2)));
startPill.setAttribute("r", pillRad);
startPill.setAttribute("fill", "#55aaff");
startPill.setAttribute("opacity", pillOpacity + "%");
//startPill.setAttribute("cursor", "move");
svg.appendChild(startPill);

const periodPill = document.createElementNS(svgNS, "rect");
periodPill.setAttribute("class", "draggable");
periodPill.setAttribute("id", "period");
periodPill.setAttribute("x", -diamondSide / 2);
periodPill.setAttribute("y", -diamondSide / 2);
periodPill.setAttribute("width", diamondSide);
periodPill.setAttribute("height", diamondSide);
periodPill.setAttribute("transform", "translate(" + (control_W / 2) + ", " + (top_padding + (control_H / 2)) + ") rotate(45)");
periodPill.setAttribute("fill", "#55aaff");
periodPill.setAttribute("opacity", pillOpacity + "%");
periodPill.addEventListener("click", function() {
    //don't keep recreating the menu if one already exists
    if (document.getElementById("periodDD") == null) {
        var menu = createPeriodDD();
    }
});
svg.appendChild(periodPill);

const endPill = document.createElementNS(svgNS, "circle");
endPill.setAttribute("class", "draggable");
endPill.setAttribute("id", "endPill");
endPill.setAttribute("cx", (control_W - right_padding));
endPill.setAttribute("cy", (top_padding + (control_H / 2)));
endPill.setAttribute("r", pillRad);
endPill.setAttribute("fill", "#55aaff");
endPill.setAttribute("opacity", pillOpacity + "%");
//endPill.setAttribute("cursor", "move");
svg.appendChild(endPill);

const startLabel = document.createElementNS(svgNS, "text");
startLabel.setAttribute("class", "ibm-plex-sans-labelText");
startLabel.setAttribute("y", labelOffset);
startLabel.setAttribute("text-anchor", "left");
startLabel.textContent = "Start time";
startLabel.setAttribute("x", left_padding - (measureTextWidth(startLabel.textContent)) / 2);
svg.appendChild(startLabel);

const periodLabel = document.createElementNS(svgNS, "text");
periodLabel.setAttribute("class", "ibm-plex-sans-labelText");
periodLabel.setAttribute("y", labelOffset);
periodLabel.setAttribute("text-anchor", "center");
periodLabel.textContent = "Period";
periodLabel.setAttribute("x", (control_W / 2) - (measureTextWidth(periodLabel.textContent)) / 2);
svg.appendChild(periodLabel);

const endLabel = document.createElementNS(svgNS, "text");
endLabel.setAttribute("class", "ibm-plex-sans-labelText");
endLabel.setAttribute("y", labelOffset);
endLabel.setAttribute("text-anchor", "right");
endLabel.textContent = "End time";
endLabel.setAttribute("x", (control_W - right_padding) - (measureTextWidth(endLabel.textContent)) / 2);
svg.appendChild(endLabel);

function measureTextWidth(text) {
    const testDiv = document.getElementById("Test");
    testDiv.innerText = text; // Set the text to measure
    // Measure width after rendering
    const width = testDiv.clientWidth;
    return width;
}

function createPeriodDD() {
    const P = [100, 1, 1, 1, 1, 7]; //enumerated values
    // 菜单创建和文本填充的逻辑在这里实现,目前DOM中已能看到文本元素但无法显示
}

我已经确认菜单文本元素确实被正确创建并添加到DOM中,但就是看不到显示效果,也没有选中边界框,实在摸不着头脑,希望各位能帮我找出问题所在,谢谢啦!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 14:13:09