【问题标题】:Forcing IE8 to rerender/repaint :before/:after pseudo elements强制 IE8 重新渲染/重新绘制 :before/:after 伪元素
【发布时间】:2012-01-31 23:49:43
【问题描述】:

所以我一直在玩弄这个日历式的东西:

  • div 网格(模仿表格)
  • 将鼠标悬停在表格单元格上会显示一个带有 2 个图标的工具提示,每个图标由一个带有 :before 和 :after 元素的 div 组成
  • 图标的颜色会根据悬停单元格的颜色及其上一个同级单元格的颜色(单元格的颜色类应用于图标)而改变。

精简小提琴:http://jsfiddle.net/e9PkA/1/

这在除 IE8 及以下的所有浏览器中都可以正常工作(IE lte 7 和我永远不会成为朋友,但 IE8 会很高兴)。

IE8 会注意到 classNames 的变化并相应地更新 div 的颜色,但完全忽略 :before 和 :after 声明所隐含的颜色变化,例如:

.wbscal_icon_arrival:before {
    width: 12px;
    height: 4px;

    left: -8px;
    top: 6px;
    background-color: silver;
}

.wbscal_icon_arrival.wbscal_full:before {
    background-color: #ff0000 !important; 
}

在上面的小提琴中,:before/:after 元素只着色一次:第一次显示工具提示。

在另一个版本中,每次我将鼠标移出“表格”div 时,它都会更新,但如果在悬停“单元格”div 边框时工具提示被隐藏,则不会更新。

我已经尝试通过在元素/其父级/主体中添加/删除其他类、编辑/访问样式属性等等来强制触发重绘,所以我想这不是你的平均重绘问题。

是否有 JS hack 可以解决此问题并强制 :before/:after 更新?

【问题讨论】:

    标签: javascript css internet-explorer-8 pseudo-element


    【解决方案1】:

    一直试图找出同样的事情。除非您对内容进行更改,否则 IE8 基本上不会重绘伪元素。所以我在这里修改了你的例子(只是 CSS)http://jsfiddle.net/lnrb0b/VWhv9/。我已将 width:0overflow:hidden 添加到伪元素,然后将 content:"x" 添加到每个颜色选项,其中 x 是递增的空格数。

    它对我有用;希望对你有帮助!

    【讨论】:

    • 我既震惊又惊讶。谢谢。
    • 别担心 - 这很奇怪!
    • 对于那些仍然有点困惑的人——你可能需要添加一个内容:'';到每个声明,确保相同元素的不同状态的空格数不同。
    • 我从事 Web 开发已有 11 年了,然而,IE 仍然呈现出一些最有创意和疯狂的错误。非常感谢您的修复!
    • 这简直太荒谬了:P 谢谢@Inrbob
    【解决方案2】:

    content:"x" 添加到伪元素的每个声明中,并为元素的每个不同状态增加空格数,从而彻底解决问题。

    基本上,思路是告诉IE8每个状态的内容略有不同,所以重绘每个状态的内容。因此,如果内容相同,我们会用空格“伪造”它。太棒了!!

    【讨论】:

      【解决方案3】:

      @lnrbob 非常好的答案!

      我遇到的问题是我使用了复选框输入的前后伪类,它们使用一些父属性来显示它们的内容(因为在那里很容易实现翻译)。

      所以它们看起来像:

      input:before {
          content: "" attr(data-on) "";
      }
      
      input:after {
          content: "" attr(data-off) "";
      }
      

      标记看起来像这样:

      <div class="switch off" data-on="It is ON" data-off="It is OFF">
          <input id="switch" name="switch" type="checkbox" class="off">
      </div>
      

      我在 jquery 中所做的修改如下所示:

      var mSwitch = $('div.switch'),
          on = $.trim(mSwitch.attr('data-on')),
          off = $.trim(mSwitch.attr('data-off'));
      // remove any spaces due to trim
      mSwitch .attr('data-on', on);
      // add a space
      mSwitch .attr('data-on', on + ' ');
      mSwitch .attr('data-off', off);
      mSwitch .attr('data-off', off + ' ');
      

      我在设置/删除类之后调用这个修改来改变“复选框”的样式,在这种情况下它是一个开关按钮:D

      因此,如果某些硬核测试人员无限地自动单击输入,则这样您就不会因过多的空格字符而导致堆栈溢出;)

      这样:

      <div class="switch on" data-on="ON" data-off="OFF                                                                                                                                                                                                                                                 ">
      

      【讨论】:

        【解决方案4】:

        基本上IE8不会重绘伪元素,除非你改变了内容,所以你可以像下面这样修改:

        .wbscal_icon_arrival:before {
            width: 12px;
            height: 4px;
            left: -8px;
            top: 6px;
            background-color: silver;
            content: '';
        }
        
        .active .wbscal_icon_arrival:before {
            background-color: gold;
            content: ' ';
        }
        

        【讨论】:

          【解决方案5】:

          我现在在 IE11 和 Edge 中遇到了类似的问题。

          悬停时,我尝试将内容从“v”更改为“V”。 => 不适用于任何微软浏览器。

          但是,如果我将字母更改为其他字母('w'/'W')或两个字母('vV'),则图标会更改。是的,微软。

          【讨论】:

            猜你喜欢
            • 2014-07-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-04-20
            相关资源
            最近更新 更多