Webkit bug:在将子元素大小调整为匹配大小后自动触发溢出

时间:2014-12-14 22:35:02

标签: javascript css google-chrome safari webkit

我有以下简单的设置:

document.getElementById('inner').addEventListener('click', ({ target }) => {
  target.classList.add('match');
});
#container {
  background: green;
  overflow: auto;
  width: 200px;
  height: 100px;
}

#inner {
  width: 210px;
  height: 110px;
}

#inner.match {
  width: 200px;
  height: 100px;
}
<div id="container">
  <div id="inner"></div>
</div>

单击内部元素后,我希望父元素上的滚动条消失,因为这两个元素现在具有匹配的大小。这在Firefox中可以正常工作 但是,容器元素不会丢失Chrome中的滚动条,如下面的屏幕截图所示:

Sample image

滚动条本身会创建一个足以产生溢出的偏移量 这是特定于webkit的问题吗?对于这个(看似微不足道的)问题,是否存在跨浏览器,可靠的解决方案?

我正在寻找一种不会改变父级属性的解决方案,因为我的内容(#inner)将放置在我无法控制的DOM中。

到目前为止,我已尝试在不同的执行点隐藏/显示和/或分离/重新插入元素,但问题仍然存在,可能是因为操作被简单地优化掉了。

问题出现在Jsfiddle和Stack片段中。

该错误已在Webkit Bugzilla上提交。

4 个答案:

答案 0 :(得分:4)

在应用样式后,不涉及寻址父级的变通方法是force a browser redraw

document.getElementById('inner').addEventListener('click', ({ target }) => {
  target.classList.add('match');
  //Force redraw
  target.style.display='none';
  target.offsetHeight; //Won't work without this
  target.style.display='';
});
#container {
  background: green;
  overflow: auto;
  width: 200px;
  height: 100px;
}

#inner {
  width: 210px;
  height: 110px;
}

#inner.match {
  width: 200px;
  height: 100px;
}
<div id="container">
  <div id="inner"></div>
</div>

我无法保证这是一个始终如一的解决方案(请参阅关于强制重绘可能问题的链接线程),但至少在这个特定情况下,这似乎适用于我的初始测试。
我已经向Webkit提交了一个描述上述所有行为的错误,但在此之前,这是一个可行的选择。

答案 1 :(得分:1)

以下是解决此问题的三种解决方案。

解决方案1 ​​

$('.i').on('click', function() {
    var t = $(this);
    t.css({
        width: '100%',
        height: '100%'
   });
});

解决方案2

$('.i').on('click', function() {
    var t = $(this);
    t.css({
        width : '200px',
        height : '100px',
        zoom : 0.5
   });
    setTimeout(function(){
    t.css({
        zoom : 1
    })}, 1);    
});

解决方案3

使用动画

$('.i').on('click', function() {
    var t = $(this);
    t.css({
        width: '100%',
        height: '100%',
        '-webkit-animation': 'animate 0.01s, linear'
   });
});

添加到CSS:

/* Chrome, Safari, Opera */
@-webkit-keyframes animate {
    from {width: 180px; height: 100px;}
    to {width: 200px; height: 100px;}
}

答案 2 :(得分:-1)

要删除滚动条,您需要重绘父$(&#39; .c&#39;)元素。但是简单的隐藏(style =&#34; display:none;&#34;),然后show(style =&#34; display:block;&#34;)根本没有效果。 通过更新溢出属性,您需要每次检查更新的宽度和高度,并根据条件,您必须更改溢出属性的值。

尝试以下代码

$('.i').on('click', function() {
    var t = $(this);
    t.css({
        width: 200,
        height: 100
    })

    $('.c').slideUp(0).slideDown(0); // added
});

我尝试使用值为0的jquery slideUp()和slideDown()方法。它在windows chrome和safari上工作正常。我希望它也适用于Mac的浏览器。 仅供参考:使用值为0的jquery hide()和show()方法也可以正常工作。

答案 3 :(得分:-3)

在所有浏览器测试中,似乎这个问题可以重现并与基于webkit的浏览器隔离。

我建议查看是否有包含webkit的开放票证,或者提交错误报告:https://bugs.webkit.org/

This old ticket似乎与您的问题有关。除了操纵父元素(你说的不实用)之外,我不确定是否有任何解决方法。