javascript - 检测并修复固定的绝对错误

标签 javascript html css

对于一个小元素,我在 Firefox(移动和桌面)中遇到了一个我认为是错误的行为:使用 chromium 我没有错误,检查 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>

现在的问题:

  1. 显然,我的解决方法并不完全令人满意:平滑过渡丢失,并且在该示例中,如果鼠标快速移入和移出触发器,固定元素仍悬在中间。您是否有更好的解决方法的想法,或者设计没有错误的相同行为?

  2. 在javascript测试中,我标记了一行。删除该行使测试在 Firefox 上通过。我不明白为什么,但也许这可以用来不太粗略地解决错误?

最佳答案

可能会产生与您想要的相同结果的解决方法是将 .child 移动到移动容器之外,并在触发器上应用相同的转换:悬停,只需使用 margin-left 或什至 transform: translateX(200px) 以不干扰固定定位。

(使用 transform 而不是在容器上定位实际上可以解决渲染问题,但遗憾的是它也会使 position:fixed 相对于转换后的元素而不是视口(viewport)。)

/* 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;
}
<div class="trigger">
  <div class="container">
  </div>
  <div class="child"></div>
</div>

关于javascript - 检测并修复固定的绝对错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39582445/

相关文章:

javascript - 在滚动上添加类

javascript - 如何在数组工作循环内的 .click 函数内建立链接?

javascript - 谷歌地图上的固定标记

css - "float: right;"与 "float: left; margin-left: Ypx"对于 2 列布局,最佳做法是什么?

javascript - 如何使用 Javascript 验证表单中的多个字段?

javascript - ':active' class not working neither 'routerLinkActive' is working

javascript - angularJS,一个通知部分或模态,加载几秒钟然后消失

javascript - 焦点不适用于由 javascript onclick 事件触发的文本区域

javascript - jquery 事件处理程序堆叠

javascript - Ajax 表单验证的优点和缺点