对于一个小项目,我在Firefox中遇到一种行为(包括移动和桌面),我认为这是一个错误:使用chrome我没有错误,检查html触发器重新绘制并解决问题。
为了实现响应式设计,我有一个绝对定位的侧面板,可以滑入和滑出。在这个侧面板中,我愿意有一个固定的元素。固定位置仅指定底部,因此固定元件应与包含面板侧向平移。然而,在firefox中,位置没有正确更新,并且固定元素不会后期翻译。搜索,我提出了一个hacky解决方法,但这个修复并不完美,并引入了其他浏览器没有的小错误。因此,我还设计了一个测试,以检查浏览器是否遇到错误,以便我只在必要时使用hack。这是从我的代码派生的最小示例。
/* Fix to programatically force fixed element repositionning */
var trigger = document.getElementById('trigger');
var container = document.getElementById('container');
var child = document.getElementById('child');
function from_and_back(evt) {
if (container.children.length) {
container.removeChild(child);
setTimeout(function() {
container.appendChild(child);
}, 300);
}
}
trigger.addEventListener('mouseenter', from_and_back);
trigger.addEventListener('mouseleave', from_and_back);
/* Simulate the bug to check whether the browser experiences it */
var bug_status = document.getElementById('bug-status');
bug_status.innerText = (function() {
//create an absolutely positionned element
var abs = document.createElement('div');
abs.style.position = 'relative';
abs.style.left = '0px';
//create a fixed element to put inside
var fix = document.createElement('div');
fix.style.position = 'fixed';
//insert it into the document
abs.appendChild(fix);
document.body.appendChild(abs);
//test
fix.getBoundingClientRect(); /************ this line *************/
abs.style.left = '20px';
var fix_left = fix.getBoundingClientRect().left;
var abs_left = abs.getBoundingClientRect().left;
//remove test elements from the document
document.body.removeChild(abs);
//send the result
return abs_left !== fix_left;
})();
/* Wrapper class to trigger the effect */
.trigger {
width: 220px;
border: 1px solid #000;
display: inline-block;
}
.trigger:hover .container {
left: 200px;
}
/* Absolutely positionned element */
.container {
position: relative;
width: 20px;
height: 20px;
left: 0px;
background: #aaa;
transition: all .25s ease-out;
}
/* Fixed element inside the absolute one */
.child {
position: fixed;
width: 20px;
height: 20px;
background: #aaa;
top: 100px;
}
<!-- Display the bug test result -->
Your browser has the bug : <span id='bug-status'></span>
<br/>
<br/>
<div class="trigger">
<!-- Demonstrate the error without any fix -->
<span>Reference</span>
<br/>
<div class="container">
<div class="child"></div>
</div>
</div>
</div>
<!-- Apply the fix fix -->
<div class="trigger" id="trigger">
<span>Fixed</span>
<br/>
<div class="container" id="container">
<div class="child" id="child"></div>
</div>
</div>
现在问题:
显然我的解决方法并不完全令人满意:平滑过渡失去了,在示例中,如果鼠标快速移入和移出触发器,固定元素将保持悬空在中间。您是否有更好的解决方法的想法,或没有错误的相同行为设计?
在javascript测试中,我标记了一行。删除该行会使测试通过Firefox。我不明白为什么,但也许这可以用来粗略地解决这个问题?
答案 0 :(得分:1)
可能提供相同结果的解决方法是将.child
移到移动容器之外,并在触发器上应用相同的转换:悬停,只使用margin-left
甚至{{1}不要搞乱固定的定位。
(使用transform: translateX(200px)
而不是在容器上定位实际上会解决渲染问题,但遗憾的是它也会使位置:相对于转换后的元素而不是视口固定。)
transform
/* Wrapper class to trigger the effect */
.trigger {
width: 220px;
border: 1px solid #000;
display: inline-block;
}
.trigger:hover .container {
left: 200px;
}
.trigger:hover .child {
margin-left: 200px;
}
.container {
position: relative;
width: 20px;
height: 20px;
left: 0px;
background: #aaa;
transition: all .25s ease-out;
}
.child {
position: fixed;
width: 20px;
height: 20px;
background: #aaa;
top: 100px;
margin-left: 0;
transition: all .25s ease-out;
}