JavaScript生成的SVG元素尺寸与HTML直接定义的不一致问题求助
JavaScript生成的SVG元素尺寸与HTML直接定义的不一致问题求助
嘿,各位开发者朋友,我最近碰到一个特别头疼的问题,想请大家帮忙诊断下!
问题描述
我用JavaScript动态生成带SVG图标的按钮,但这些SVG的表现和直接写在HTML里的完全不一样:
- JS生成的SVG容器始终固定为300px×150px,里面的path元素保持24×24像素大小,缩在容器的右上角;不管怎么调整CSS样式或SVG属性,path都不跟着缩放。
- 但把完全相同的元素直接写在HTML里时,SVG就能完美匹配父按钮的尺寸,表现完全正常。
我试过给SVG加各种CSS规则、修改SVG的属性,SVG元素本身会有反应,但里面的path纹丝不动。我怀疑是JS创建元素的方式出了问题,但实在找不到具体原因,求大家支招!
我当前的代码
JavaScript代码
var controls = true if (controls == true) { // 生成重置按钮的SVG var resetSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); var resetSvgPath = document.createElementNS( "http://www.w3.org/2000/svg", "path", ); resetSvg.setAttribute("class", "icon reset-icon"); resetSvg.setAttribute("viewbox", "0 0 24 24"); // 这里是关键问题点! resetSvg.setAttribute("preserveAspectRatio", "xMinYMax meet"); resetSvg.setAttribute("fill-rule", "evenodd"); resetSvg.setAttribute("clip-rule", "evenodd"); resetSvgPath.setAttribute( "d", "M2.458 9.012c-.297.947-.458 1.955-.458 3 0 5.52 4.481 10 10 10 5.52 0 10-4.48 10-10 0-5.519-4.48-10-10-10-2.121 0-4.083.668-5.703 1.796l1.703 2.204h-6.58l1.935-6.012 1.718 2.223c1.958-1.389 4.346-2.211 6.927-2.211 6.623 0 12 5.377 12 12s-5.377 11.988-12 11.988-12-5.365-12-11.988c0-1.036.132-2.041.379-3h2.079zm10.35-3.012c.292.821.375 1.346 1.01 1.609.637.264 1.073-.052 1.854-.423l1.142 1.142c-.373.787-.687 1.218-.423 1.854.262.634.784.716 1.609 1.009v1.617c-.816.29-1.347.375-1.61 1.01-.264.636.052 1.071.424 1.853l-1.142 1.142c-.79-.375-1.219-.687-1.85-.424-.639.265-.723.793-1.014 1.611h-1.616c-.292-.821-.375-1.347-1.01-1.61-.637-.264-1.072.052-1.854.423l-1.142-1.142c.366-.771.689-1.212.423-1.854-.263-.635-.793-.719-1.609-1.009v-1.617c.817-.29 1.346-.373 1.609-1.009.264-.637-.051-1.07-.423-1.854l1.142-1.142c.788.374 1.218.687 1.854.423.635-.263.719-.792 1.01-1.609h1.616zm-.808 8c-1.105 0-2-.896-2-2 0-1.105.895-2.001 2-2.001 1.104 0 2 .896 2 2.001 0 1.104-.896 2-2 2z", ); resetSvg.appendChild(resetSvgPath); var resetButton = document.createElement("button"); resetButton.classList.add("reset-button"); resetButton.appendChild(resetSvg); document.body.appendChild(resetButton); }
CSS代码
button { width: 5rem; }
问题根源
你猜怎么着!问题出在**viewbox属性的大小写**上!
SVG标准里这个属性是**viewBox**(注意字母B是大写的):
- 在HTML中,属性名是大小写不敏感的,所以你写小写的
viewbox,浏览器会自动转换成正确的viewBox; - 但在JavaScript操作DOM时,SVG元素属于SVG命名空间,DOM对SVG属性的大小写是敏感的——你用
setAttribute("viewbox", "...")设置的是一个不被SVG识别的无效属性,相当于SVG没有正确设置视口,所以它会 fallback 到默认的300px×150px尺寸,而path因为没有视口约束,就保持了原始的24×24大小,最终导致错位。
解决方法
只需要把viewbox改成正确的viewBox就行!
修改JS里的这一行:
// 原来的错误写法 resetSvg.setAttribute("viewbox", "0 0 24 24"); // 改成正确的大小写 resetSvg.setAttribute("viewBox", "0 0 24 24");
或者你也可以用DOM API直接设置viewBox对象,效果是一样的:
resetSvg.viewBox.baseVal.x = 0; resetSvg.viewBox.baseVal.y = 0; resetSvg.viewBox.baseVal.width = 24; resetSvg.viewBox.baseVal.height = 24;
验证效果
改完之后,JS动态生成的SVG就会和直接写在HTML里的表现完全一致了——SVG会根据父按钮的尺寸自动缩放,里面的path也会跟着适配容器大小。
这个坑真的太容易踩了,毕竟HTML里大小写不敏感,很容易忽略DOM操作里的大小写要求😅
备注:内容来源于stack exchange,提问作者Paul Lovell
相关产品推荐
相关产品推荐

