【问题标题】:SVG: Click underlying svgSVG:单击底层 svg
【发布时间】:2017-09-21 16:56:40
【问题描述】:

我有这个页面,上面有 2 张 svg 图片。 似乎 svg (item1) 图像重叠并阻止点击底层 svg (item2)

我尝试在元素上使用指针事件,但我似乎无法让它在底层 item2 上工作。

也许 de svg 仍在阻止“点击事件”

这是代码:

HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="js/main.js"></script>
<body>
    <div id="main">
        <div id="item1">
            <svg class="crossSvg">
                <line class="verticalLine" x1="50%" y1="0" x2="50%" y2="100%"></line>
                <line class="horizontalLine" x1="0" y1="50%" x2="100%" y2="50%"></line>
                <rect class="itemSquare" x="50%" y="50%" width="10" height="10" transform="translate(-5,-5)"/>
                <text class="itemTitle" x="50%" y="50%" transform="translate(10,-10)">item1</text>
            </svg>
            <svg class="closeSvg">
                <rect class="closeSquare" x="0" y="0" width="10" height="10"/>
                <line x1="90%" y1="50%" x2="91%" y2="51%"></line>
            </svg>
        </div>
        <div id="item2">
            <svg class="crossSvg">
                <line class="verticalLine" x1="50%" y1="0" x2="50%" y2="100%"></line>
                <line class="horizontalLine" x1="0" y1="50%" x2="100%" y2="50%"></line>
                <rect class="itemSquare" x="50%" y="50%" width="10" height="10" transform="translate(-5,-5)"/>
                <text class="itemTitle" x="50%" y="50%" transform="translate(10,-10)">item2</text>
            </svg>
            <svg class="closeSvg">
                <rect class="closeSquare" x="0" y="0" width="10" height="10"/>
                <line x1="90%" y1="50%" x2="91%" y2="51%"></line>
            </svg>
        </div>
    </div>
</body>

JAVASCRIPT:

$( document ).ready(function() {
    $('.itemSquare').on('click', function(){
        alert("Hello! I am an alert box!!");
    });
});

CSS:

#main{
    width: 100vw;
    height: 100vh;
}

#item1, #item2{
    position: absolute;
    width: 200vw;
    height: 200vh;
}
/* ---- positioning items ---- */
#item1{
    left: -90vw;
    top: -80vh;
    z-index:100;
}

#item2{
    left: -50vw;
    top: -70vh;
}
/* ---- item content ---- */
.itemContent{
    display: none;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 90vw;
    overflow: hidden;
    padding: 5px;
}

/* ---- SVG's ----- */
.crossSvg{
    position: absolute;
    width: 100%;
    height: 100%;
    background: none;
    pointer-events: all;
}

.verticalLine, .horizontalLine {
    stroke: black; 
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.itemSquare{
    display: hidden;
    fill: black;
    stroke: black;
    stroke-width: 1;
    shape-rendering: crispEdges;
    pointer-events: fill;
}

.closeSvg{
    position: absolute;
    top: 50%;
    left: 95%;
    margin-top: -5px;
}

.closeSquare{
    fill: black;
    stroke: black;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

我把这个放在这个小提琴中: https://jsfiddle.net/fme21qx9/3/

【问题讨论】:

  • 你是 100% 正确的,你不能点击底层 svg。
  • @skobaljic 我知道,但为什么不,我怎样才能让它工作......
  • 你不能这样。您必须将单击事件绑定到某个父元素,然后从鼠标位置进行计算……或者根据需要使用 z-index 以某种方式重新排序您的 SVG(例如:在 Photoshop 中选择图层)。浏览器无法知道您想要单击的 SVG(图层),因为它们都在另一个之上 - 所以它返回顶部。
  • @skobaljic 我已经读过,它可能不得不将 div 放在彼此之上,有背景,并让底层的一个接收点击事件......
  • developer.mozilla.org/en-US/docs/Web/CSS/pointer-events 除了指示该元素不是鼠标事件的目标之外,值 none 还指示鼠标事件“穿过”该元素并以该元素“下方”的任何内容为目标.

标签: jquery html css svg


【解决方案1】:

您需要禁用包装元素 (div#item1) 和 SVG (svg.crossSvg) 的指针事件,因为 SVG 具有不同的指针上下文。

如果将其添加到 CSS 的末尾,它可以正常工作:

#item1 {
  pointer-events: none;
}
#item1 .crossSvg {
  pointer-events: none;
}

.itemSquare {
  pointer-events: all;
}

(尽管在选择器中使用 ID 进行样式设置并不是最佳做法)

编辑: 更新了您的 fiddle 以反映答案的变化以及我们在 cmets 中的讨论。

【讨论】:

  • "虽然在选择器中使用 ID 进行样式设置并不是最佳实践" 为什么不呢?我想当一个元素在 DOM 中只存在一次时,最好使用 id 而不是类?启发我!
  • 它似乎可以在不禁用 crossSvg 上的指针事件的情况下工作
  • @Nomistake 是的,用 ID 识别 DOM 中单个出现的元素是好的(例如,JS 可以快速找到它),但通过 ID 进行样式设置则不行。原因是CSS specificity 在使用 SVG 时非常高(您现在只能在选择器中包含 ID 时推翻该规则)。
  • 好的,我读了这篇文章,并且会再读一遍:-) 你会如何应用这种风格?
  • 我上一条评论中有错字(SVG -> ID*)。而且我需要更多语义类的上下文,但是(例如)您可以将它们命名为.item,在这种情况下您不需要知道它在样式中的哪个项目的上下文。如果你这样做了,那么你可以将它们命名为 .item.foo.item.bar,其中 foobar 是代表这些项目的某些用例的其他词(如果没有想到其他的话,通常是 .item.left.item.right 也可以)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 2012-10-03
  • 2022-01-23
相关资源
最近更新 更多