【问题标题】:Jquery thinks my <g> element is visible, even when display is set to none and/or visibility is set to hiddenJquery 认为我的 <g> 元素是可见的,即使显示设置为无和/或可见性设置为隐藏
【发布时间】:2020-10-30 20:44:05
【问题描述】:

请看一下我在下面创建的示例。 当您单击该按钮时,&lt;g&gt; 会切换,绿点会显示或隐藏。

奇怪的是,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,但也没有用

【问题讨论】:

  • @RobbyCornelissen 我已更新代码以使用visibility。同样的问题

标签: html jquery css svg display


【解决方案1】:

有两种不同的情况需要注意:


visibility: hidden

根据the JQuery documentationvisibility: hidden 的元素仍然被:visible 选择器视为可见:

考虑带有visibility: hiddenopacity: 0 的元素 可见,因为它们仍然占用布局中的空间。


display: none

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

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

至少在 Chrome 中,offsetWidthoffsetHeight 对于 SVG 元素是未定义的。

这给我们留下了客户端矩形,这似乎就是问题所在,因为仍然有一个与 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 中可以正常工作。但是,confusion 似乎确实有关于 getClientRects() 在内部 SVG 元素的情况下需要返回的内容。

【讨论】:

    【解决方案2】:

    切换circle 作品的可见性

    jquery源码:

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

    这里offsetWidth, offsetHeight, getClientRects()g 元素返回null

    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>

    【讨论】:

    • @mplungjan 不知道为什么 jquery 使用 offsetWidth 和 offsetHeight 而不是可见性或显示设置:(
    • @mplungjan 因为在 Chrome 中,带有display:noneg 元素仍然有一个与之关联的客户端矩形,而circle 元素没有。它在 Firefox 中正常工作,因此看起来像是 Chrome 中的一个错误。详情见我的回答。
    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2015-08-22
    • 2021-08-10
    • 1970-01-01
    相关资源
    最近更新 更多