Jquery 认为我的 <g> 元素可见,即使显示设置为 none and/or 可见性设置为隐藏

Jquery thinks my <g> element is visible, even when display is set to none and/or visibility is set to hidden

请看一下我在下面创建的示例。 单击该按钮时,<g> 会切换,绿点会显示或隐藏。

奇怪的是,is(':visible') 总是返回 true,即使 visibility 设置为 hidden

为什么会这样?

console.log('Jquery running...')

$("button").click( () => {
  var prev = $("g").attr('visibility');
  if (prev === 'hidden') {
$('g').attr('visibility', 'visible');
  } else {
$('g').attr('visibility', 'hidden');
  }

  console.log('element is visible:', el.is(':visible'));
});

var el = $('g');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>My Example</p>

<svg width="20" height="30">

<g>
<circle cx="10" cy="10" r="10" fill="green"></circle>
</g>
</svg>

<button> Toggle Dot </button>

更新

我之前也试过把display设置成none,也没用

切换 circle 作品的可见性

Jquery源代码:

jQuery.expr.pseudos.visible = function( elem ) {
    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

此处 offsetWidth, offsetHeight, getClientRects() returns null 用于 g 元素

console.log('Jquery running...')

$("button").click(() => {
  el.toggle();

  console.log('element is visible:', el.is(':visible'));
});

var el = $('g circle');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>My Example</p>

<svg width="20" height="30">

<g>
<circle cx="10" cy="10" r="10" fill="green"></circle>
</g>
</svg>

<button> Toggle Dot </button>

有两个单独的案例值得关注:


visibility: hidden

根据 the JQuery documentation,具有 visibility: hidden 的元素仍然被 :visible 选择器视为可见:

Elements with visibility: hidden or opacity: 0 are considered visible, since they still consume space in the layout.


display: none

具有 display: none 的元素不会在布局中占用 space,因此理论上不应被 :visible 选择器选中。当我们查看用于确定元素是否可见的 JQuery code 时,它基于三个值:

jQuery.expr.pseudos.visible = function( elem ) { 
        return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

至少在 Chrome 中,offsetWidthoffsetHeight 未定义 SVG 元素。

剩下客户端 rect,这似乎就是问题所在,因为仍然有一个客户端 rect 与 g 元素相关联,其 display 设置为 none:

console.log('Jquery running...')

$('button').click(() => {
  var prev = $('g').css('display');
  if (prev === 'none') {
    $('g').css('display', 'block');
  } else {
    $('g').css('display', 'none');
  }
  
  console.log(el[0].getClientRects().length); // 1
})

var el = $('g');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>My Example</p>

<svg width="20" height="30">

<g>
<circle cx="10" cy="10" r="10" fill="green"></circle>
</g>
</svg>

<button> Toggle Dot </button>


看起来像是 Chrome 中的错误,因为它在 Firefox 中可以正常工作。但是,对于内部 SVG 元素,getClientRects() 需要 return 似乎 confusion