我有一个像这样的 SVG 文件
<svg class="icon" viewBox="0 0 16 16">
<use href="assets/icons.svg#my-fancy-icon"></use>
</svg>
使用 JavaScript,如何确定
href
元素的 use
属性是否指向实际存在的元素?
<use>
元素的边界:宽度和高度:0 =不存在成功附加 svg 元素后,它将返回宽度和高度值 > 0(调用
getBBox()
)。
如果不是 –
getBBox()
将返回宽度和高度值 0。document.createElement()
(缺少正确的命名空间)而不是 document.createElementNS()
时。
let useEls = document.querySelectorAll('use');
useEls.forEach(function(use) {
let bb = use.getBBox();
let [width, height] = [bb.width, bb.height];
if (width == 0 && height == 0) {
use.closest('svg').classList.add('notavailable')
}
})
svg {
height: 10em;
border: 1px solid #ccc;
display: inline-block;
}
.notavailable {
border: 1px solid red;
}
<svg id="svgIcons" class="svgIcons" viewBox="0 0 100 100" style="position:absolute; height:0; width:0;" xmlns="http://www.w3.org/2000/svg">
<symbol id="home" viewBox="0 0 34 48">
<path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" />
</symbol>
</svg>
<svg viewBox="0 0 34 48">
<use href="#home" />
</svg>
<svg viewBox="0 0 34 48">
<use href="#notExistent" />
</svg>
这样我们还可以检查被 <use>
隐藏的不可见
display: none
元素,这些元素会被之前的检查方法忽略。
checkUseEls();
function checkUseEls() {
// collect missing references
let missingRefs = [];
//add temporary hidden svg
let svgTmp = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svgTmp.setAttribute('style', 'position:absolute; width:0; height:0;visibility:hidden');
document.body.appendChild(svgTmp);
//add cloned use els
let useEls = document.querySelectorAll('use');
useEls.forEach(function(use) {
let cloned = use.cloneNode();
cloned.setAttribute('style', 'display:block!important')
svgTmp.appendChild(cloned)
let bb = cloned.getBBox();
let [width, height] = [bb.width, bb.height];
if (width == 0 && height == 0) {
missingRefs.push(cloned.getAttribute('href'))
}
})
svgTmp.remove();
console.log(missingRefs)
}
svg {
height: 10em;
border: 1px solid #ccc;
display: inline-block;
}
.notavailable {
border: 1px solid red;
}
<svg id="svgIcons" class="svgIcons" viewBox="0 0 100 100" style="display:none" xmlns="http://www.w3.org/2000/svg">
<symbol id="home" viewBox="0 0 34 48">
<path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" />
</symbol>
<symbol id="homeHidden" viewBox="0 0 34 48">
<path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" />
</symbol>
</svg>
<svg viewBox="0 0 34 48">
<use href="#home" />
</svg>
<svg viewBox="0 0 34 48" style="display:none">
<use href="#notExistent" />
</svg>
<svg viewBox="0 0 34 48">
<use href="#homeHidden" style="display:none"/>
</svg>
符号 #homeHidden 存在但隐藏。通过将
display:block
应用于它的克隆实例,我们可以检查它的高度。
您还可以搜索所有定义,例如
<symbol>
元素
findMissingUseDefs();
function findMissingUseDefs() {
// collect missing references
let missingRefs = [];
//add cloned use els
let useEls = document.querySelectorAll("use");
useEls.forEach((use) => {
let href = use.getAttribute("xlink:href") ?
use.getAttribute("xlink:href") :
use.getAttribute("href");
let id = href.replace("#", "");
let defs = document.querySelectorAll(`${href}`);
if (!defs.length) {
missingRefs.push(href);
}
});
console.log(missingRefs);
}
svg {
height: 10em;
border: 1px solid #ccc;
display: inline-block;
}
.notavailable {
border: 1px solid red;
}
<svg id="svgIcons" class="svgIcons" viewBox="0 0 100 100" style="display:none" xmlns="http://www.w3.org/2000/svg">
<symbol id="home" viewBox="0 0 34 48">
<path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" />
</symbol>
<symbol id="homeHidden" viewBox="0 0 34 48">
<path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" />
</symbol>
</svg>
<svg viewBox="0 0 34 48">
<use href="#home" />
</svg>
<svg viewBox="0 0 34 48" style="display:none">
<use href="#notExistent" />
</svg>
<svg viewBox="0 0 34 48">
<use href="#homeHidden" style="display:none"/>
</svg>
如果您使用外部 svgs,您将需要获取所有这些文件并查询解析的文件。总而言之,检查 bbox 可能是最简单的方法。
试试这个方法:
const icon = document.querySelector(".use");
if (icon.firstElementChild === "USE") //...do something