使用JavaScript(无库)操作SVG视口

51

我正在尝试在JavaScript中更改SVG元素的视口(viewbox)。基本上,我正在绘制一个二叉搜索树,当它变得太宽时,我希望更改视口以缩小树,以便适应窗口。目前我正在使用:

if(SVGWidth>=1000){
  var a = document.getElementById('svgArea');
  a.setAttribute("viewbox","0 0 " + SVGWidth + " 300");
}

HTML的代码如下:

<svg id="svgArea" xmlns="w3.org/2000/svg"; xmlns:xlink="w3.org/1999/xlink"; width="1000" height="300" viewBox="0 0 1000 300">

我还尝试使用setAttributeNS('null',...),但那似乎也不起作用。我注意到一个奇怪的事情是当我弹出警告框(a)时,它会显示[object SVGSVGElement],这看起来很奇怪。感谢任何帮助。


请问您为什么不想使用库? - Rene Pot
我应该补充一下,SVGWidth 可能是一个不好的变量名,应该改为 treeWidth。此外,SVG 的 HTML 代码如下: <svg id="svgArea" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="300" viewBox="0 0 1000 300"> - Andrew Clear
6
我没有使用库,因为我专注于学习JavaScript。我的下一个项目将加入库,但我认为从原生JavaScript开始会更好。 - Andrew Clear
6
使用库来实现这个可能会让人感到沮丧,因为它应该能够工作,而且只会限制操作者对DOM操作的总体理解(因此他们将完全依赖于该库)。虽然我们不应该期望深入理解到汇编级别,但了解你已经在其中工作的东西如何实际运作总是很有帮助的,而不是依赖于库。 - Anthony
4个回答

100

看到 SVG 的上下文会更好,但以下代码适用于纯 SVG 文档:

shape = document.getElementsByTagName("svg")[0];
shape.setAttribute("viewBox", "-250 -250 500 750"); 
也许是因为viewBox区分大小写?

5
就这么看吧,如果它没那么容易,那就更难了。而且我之前从来没有尝试过修改实际的SVG元素属性,所以我们两个都学到了东西。 - Anthony
7
我犯了同样的错误。 - Joseph Jaquinta
11
对于动态创建的SVG,必须使用createElementNS来创建SVG元素,否则设置属性viewBox将不起作用。参考:https://dev59.com/fF4b5IYBdhLWcg3wvT-w#28734954 - Benjamin Intal
1
我认为应该是 setAttributeNs(null, "viewBox", ...),而 setAttribute 只是 偶然 能够工作,但未来可能无法工作。如果我错了,请纠正我,因为我不是100%确定。 - Charles L.
1
我可以确认 viewBox 是区分大小写的。 - Code4R7
显示剩余2条评论

12

您的代码中有一个错误:"viewbox"与"viewBox"不同,B要大写。请更改代码为:

a.setAttribute("viewBox","0 0 " + SVGWidth + " 300");

我认为现在的回答已经回答了这个问题。 'b' 是它不能工作的原因。然而,user3434597应该先阅读@Anthony的早期答案。也许他会删除这个答案。 - akauppi

0
此外,如果您想动态设置视图框尺寸,则应使用ES6模板文字而不是字符串连接。
shape = document.getElementsByTagName("svg")[0];
const view = `${xValue} ${yValue} ${width} ${height}`; // template literals
shape.setAttribute("viewBox", view); 

0

我有一个非常类似的用例,其中调整SVG大小对于响应式设计至关重要。

const windowWidth = window.innerWidth ||
  document.documentElement.clientWidth ||
  document.body.clientWidth;

const windowHeight = window.innerHeight ||
  document.documentElement.clientHeight ||
  document.body.clientHeight;

// used getElementById for specific SVG
const shape = document.getElementById("background-svg");

function onWindowResize(){
console.log(windowWidth, windowHeight);

if (windowWidth < 600 || windowHeight < 900) {
  shape.setAttribute("viewBox", "0 0 400 800");
}

// Added an Event Listener
window.addEventListener("resize", onWindowResize);

这种方法对我来说效果不错,但我希望还有改进的空间,很高兴能找到其他的解决方案。祝编码愉快!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接