React 渲染 SVG 会覆盖页面上的其他 SVG
React rendering SVG overwrites other SVGs on the page
在我的 next.js
应用程序中使用 babel-plugin-inline-react-svg
,我将一些 SVG 导入到我的 React v16.0.0
组件中,就像这样。
import React from 'react';
import Close from './close.svg';
import Chevron from './right.svg';
import EmptyCart from './empty.svg';
const Component = props => (
<div>
<Close />
<EmptyCart />
<Chevron />
</div>
);
当我 运行 该代码时,页面呈现时 3 个 SVG 都相同,如下所示:
我首先渲染的 SVG 中的任何一个似乎都接管了所有其他 SVG。如果我把 <EmptyCart />
放在第一位,它们都会是购物车图标。但真正的问题在于:当我检查 DOM 时,SVG 似乎都是正确的(它们彼此完全不同)。
有人以前看过这个吗? DOM 怎么可能说一件事而浏览器呈现另一件事呢?
查看其他 SVG 也会有所帮助,但如果它们相似且 ID 匹配,那么这就是您的问题。
<path id="4eeded6c-befb-41ba-a055-83a9e4ddc009" d="M3.632 3.182H1.091A1.09 1.09 0 0 1 1.09 1h3.322c.467 0 .883.297 1.033.74l4.096 12.046.036.134c.083.406.53.777.928.78l8.87.056c.39.002.831-.361.925-.816l1.552-6.017a1.09 1.09 0 1 1 2.112.545l-1.539 5.96c-.285 1.417-1.625 2.518-3.064 2.51l-8.869-.057c-1.408-.008-2.718-1.073-3.036-2.451L3.632 3.182zM9.272 23a2.191 2.191 0 0 1-2.181-2.201c0-1.216.977-2.2 2.182-2.2s2.181.984 2.181 2.2A2.191 2.191 0 0 1 9.273 23zm10.91 0A2.191 2.191 0 0 1 18 20.799c0-1.216.977-2.2 2.182-2.2s2.181.984 2.181 2.2A2.191 2.191 0 0 1 20.182 23z"/>
您可以在此处看到此 ID 已在 SVG 本身内被定位和重用:
<use xlink:href="#4eeded6c-befb-41ba-a055-83a9e4ddc009"/>
这是一个常见问题,尤其是从 photoshop 等应用程序导出时。为了避免在我使用 svg 时发生冲突,我手动更改所有 ID 以确保唯一性。
如果有帮助,我创建了一个代码笔,其中包含更多有关如何重用 svg 的示例:https://codepen.io/peter-mouland/pen/JErvZY
您应该为配置文件中的每个 svg 图标分配不同的 ID。像这样:
// SVG are imported as react components
{
test: /\.svg$/,
use: [
{
loader: 'babel-loader',
},
{
loader: 'react-svg-loader',
options: {
svgo: {
plugins: [
{
removeTitle: true,
},
{cleanupIDs: {
prefix: {
toString() {
this.counter = this.counter || 0;
return `id-${this.counter++}`;
}
}
}},
],
floatPrecision: 3,
},
},
},
],
include: paths.svg,
},
问题很可能是 SVG 之间的 ID 不唯一,如上所述。有一些加载程序可以自动为您处理这个问题,这样您就不必手动更改所有 ID 和对它们的引用。看看这个:https://github.com/SilverFox70/svg-react-loader
此问题可能与 SVG 中的非唯一 ID 有关。
svg 生成器通常可以 return 具有相同 ID 的内容,例如 <mask id="mask0" />
然后由 <g mask="url(#mask0)"/>
.
引用
如果您有两个具有相同遮罩 ID 的不同 SVG,您可能会在渲染两个不同图标时遇到问题。
最简单的解决方案是为每个 <mask />
指定一个唯一的 ID,然后不要忘记更新 <g />
中的引用。
在我的例子中,两个 SVG 之间的冲突是因为它们在内部具有相同的 .className
两种解决方案:
更改其中一个实习生class的名字
如果可能(例如,如果您正在使用 CRA)使用 <img src'file.svg'>
加载其中一个 svg
在某些情况下,我们会像这样定义 SVG 的样式
<svg>
<defs>
<style>.a{fill:none;}</style>
</defs>
</svg>
这里我们定义了一个class名称样式为.a
,在我的项目中所有的svg都使用相同的class名称,如果我在[=21中使用多个SVG =] 然后我的 svgs 样式被覆盖并破坏了设计
解决方案:您应该更改 classname 以避免重复 class name
我也遇到了类似的问题,因为我从 Figma 导出了图像,并且在项目中使用了它们。
所以每次我将另一个 SVG 作为组件包含在内时,它都会覆盖其中一个 SVG 并显示第一个。
仔细查看后,我发现它们实际上具有相同的id和相同的图像名称
让 fill 属性指向 pattern45550
,在我的例子中这是我的新 svg 名称
<rect width="48" height="52" fill="url(#pattern45550)"/>
将 ID 重命名为 pattern45550
<pattern id="pattern45550" patternContentUnits="objectBoundingBox" width="1" height="1">
也在下面的标签中重命名图片名称image10000000
<image id="image10000000" width="2887" height="3162" xlink:href="data:image/png;base64...
然后最后将 URL 指向 image10000000
图片
<use xlink:href="#image10000000" transform="translate(0 -0.00550212) scale(0.00034638)"/>
在我的情况下一切都很好。
当我尝试在屏幕上使用从 figma 文件下载的多个 svg,另一个 svg 覆盖另一个时,我遇到了这个问题。问题是每个 svg 中的 class 名称相似。所以我编辑了 class 名称以防止它们发生冲突
在我的 next.js
应用程序中使用 babel-plugin-inline-react-svg
,我将一些 SVG 导入到我的 React v16.0.0
组件中,就像这样。
import React from 'react';
import Close from './close.svg';
import Chevron from './right.svg';
import EmptyCart from './empty.svg';
const Component = props => (
<div>
<Close />
<EmptyCart />
<Chevron />
</div>
);
当我 运行 该代码时,页面呈现时 3 个 SVG 都相同,如下所示:
我首先渲染的 SVG 中的任何一个似乎都接管了所有其他 SVG。如果我把 <EmptyCart />
放在第一位,它们都会是购物车图标。但真正的问题在于:当我检查 DOM 时,SVG 似乎都是正确的(它们彼此完全不同)。
有人以前看过这个吗? DOM 怎么可能说一件事而浏览器呈现另一件事呢?
查看其他 SVG 也会有所帮助,但如果它们相似且 ID 匹配,那么这就是您的问题。
<path id="4eeded6c-befb-41ba-a055-83a9e4ddc009" d="M3.632 3.182H1.091A1.09 1.09 0 0 1 1.09 1h3.322c.467 0 .883.297 1.033.74l4.096 12.046.036.134c.083.406.53.777.928.78l8.87.056c.39.002.831-.361.925-.816l1.552-6.017a1.09 1.09 0 1 1 2.112.545l-1.539 5.96c-.285 1.417-1.625 2.518-3.064 2.51l-8.869-.057c-1.408-.008-2.718-1.073-3.036-2.451L3.632 3.182zM9.272 23a2.191 2.191 0 0 1-2.181-2.201c0-1.216.977-2.2 2.182-2.2s2.181.984 2.181 2.2A2.191 2.191 0 0 1 9.273 23zm10.91 0A2.191 2.191 0 0 1 18 20.799c0-1.216.977-2.2 2.182-2.2s2.181.984 2.181 2.2A2.191 2.191 0 0 1 20.182 23z"/>
您可以在此处看到此 ID 已在 SVG 本身内被定位和重用:
<use xlink:href="#4eeded6c-befb-41ba-a055-83a9e4ddc009"/>
这是一个常见问题,尤其是从 photoshop 等应用程序导出时。为了避免在我使用 svg 时发生冲突,我手动更改所有 ID 以确保唯一性。
如果有帮助,我创建了一个代码笔,其中包含更多有关如何重用 svg 的示例:https://codepen.io/peter-mouland/pen/JErvZY
您应该为配置文件中的每个 svg 图标分配不同的 ID。像这样:
// SVG are imported as react components
{
test: /\.svg$/,
use: [
{
loader: 'babel-loader',
},
{
loader: 'react-svg-loader',
options: {
svgo: {
plugins: [
{
removeTitle: true,
},
{cleanupIDs: {
prefix: {
toString() {
this.counter = this.counter || 0;
return `id-${this.counter++}`;
}
}
}},
],
floatPrecision: 3,
},
},
},
],
include: paths.svg,
},
问题很可能是 SVG 之间的 ID 不唯一,如上所述。有一些加载程序可以自动为您处理这个问题,这样您就不必手动更改所有 ID 和对它们的引用。看看这个:https://github.com/SilverFox70/svg-react-loader
此问题可能与 SVG 中的非唯一 ID 有关。
svg 生成器通常可以 return 具有相同 ID 的内容,例如 <mask id="mask0" />
然后由 <g mask="url(#mask0)"/>
.
如果您有两个具有相同遮罩 ID 的不同 SVG,您可能会在渲染两个不同图标时遇到问题。
最简单的解决方案是为每个 <mask />
指定一个唯一的 ID,然后不要忘记更新 <g />
中的引用。
在我的例子中,两个 SVG 之间的冲突是因为它们在内部具有相同的 .className
两种解决方案:
更改其中一个实习生class的名字
如果可能(例如,如果您正在使用 CRA)使用
<img src'file.svg'>
加载其中一个 svg
在某些情况下,我们会像这样定义 SVG 的样式
<svg>
<defs>
<style>.a{fill:none;}</style>
</defs>
</svg>
这里我们定义了一个class名称样式为.a
,在我的项目中所有的svg都使用相同的class名称,如果我在[=21中使用多个SVG =] 然后我的 svgs 样式被覆盖并破坏了设计
解决方案:您应该更改 classname 以避免重复 class name
我也遇到了类似的问题,因为我从 Figma 导出了图像,并且在项目中使用了它们。
所以每次我将另一个 SVG 作为组件包含在内时,它都会覆盖其中一个 SVG 并显示第一个。
仔细查看后,我发现它们实际上具有相同的id和相同的图像名称
让 fill 属性指向 pattern45550
,在我的例子中这是我的新 svg 名称
<rect width="48" height="52" fill="url(#pattern45550)"/>
将 ID 重命名为 pattern45550
<pattern id="pattern45550" patternContentUnits="objectBoundingBox" width="1" height="1">
也在下面的标签中重命名图片名称image10000000
<image id="image10000000" width="2887" height="3162" xlink:href="data:image/png;base64...
然后最后将 URL 指向 image10000000
图片
<use xlink:href="#image10000000" transform="translate(0 -0.00550212) scale(0.00034638)"/>
在我的情况下一切都很好。
当我尝试在屏幕上使用从 figma 文件下载的多个 svg,另一个 svg 覆盖另一个时,我遇到了这个问题。问题是每个 svg 中的 class 名称相似。所以我编辑了 class 名称以防止它们发生冲突