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

jQuery点击引用模板的SVG group时如何选中特定子元素添加描边

首先明确:你当前的写法取不到元素是正常的,<use> 引用的SVG模板属于Shadow DOM范畴,不会将内部节点暴露到当前文档的DOM树中,所以contents()方法无法获取到内部的<polygon>元素。
该需求完全可实现,推荐以下两种方案:

方案1:CSS变量控制(推荐)

无需修改现有DOM结构,仅需要调整模板样式和点击逻辑即可:

  1. 给#interceptor内的第一个<polygon>的描边属性用CSS变量做兜底:
<g id="interceptor">
    <ellipse cx="0" cy="15" rx="6" ry="14" fill="url(#gradient)"/>
    <polygon points="0,-20 7,10 0,0 -7,10" fill="blue" 
             stroke="var(--ship-stroke, none)" 
             stroke-width="var(--ship-stroke-width, 0)"/>
    <polygon points="0,-20 7,10 0,0" fill="darkblue"/>
</g>
  1. 点击时直接给当前.ship元素注入CSS变量即可,变量会被内部引用的模板继承,仅作用于当前实例:
$(".ship").click(function() {
    // 可选:如果需要只保留一个选中状态,先清空其他实例的描边
    $(".ship").css({
        "--ship-stroke": "none",
        "--ship-stroke-width": 0
    });
    // 给当前点击的实例添加描边
    $(this).css({
        "--ship-stroke": "white",
        "--ship-stroke-width": 1
    });
});

该方案不会增加额外DOM节点,也不会出现组内多元素多余描边的问题,性能最优。

方案2:克隆节点替换use引用(兼容旧浏览器)

如果需要兼容不支持CSS变量的老旧浏览器,可以放弃<use>复用逻辑,改为每次生成ship时直接克隆模板节点:

// 生成ship实例的逻辑替换为克隆
function createShip(shipId, transformAttr) {
    const tpl = $("#interceptor").clone().removeAttr("id");
    return $("<g></g>")
        .addClass("ship")
        .attr("id", shipId)
        .attr("transform", transformAttr)
        .append(tpl);
}
// 示例调用,插入到svg根节点
createShip("ship3", "rotate(-180,480,24) translate(480,24)").appendTo("svg");

修改后即可直接操作内部节点,点击逻辑可以按你最初的思路实现:

$(".ship").click(function() {
    // 可选:清空其他实例的描边
    $(".ship").find("polygon").first().attr({stroke: "none", "stroke-width": 0});
    // 给当前实例添加描边
    $(this).find("polygon").first().attr({stroke: "white", "stroke-width": 1});
});

内容的提问来源于stack exchange,提问作者PaulJK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:15:03