使用动态 SVG 元素时 IE 11 “崩溃”

Posted

技术标签:

【中文标题】使用动态 SVG 元素时 IE 11 “崩溃”【英文标题】:IE 11 "Crashes" when Using Dynamic SVG Elements 【发布时间】:2015-08-19 15:17:06 【问题描述】:

我最近为我公司的新 html 应用程序实现了一个自定义 SVG 图标控件。实施后不久,我们的质量部门开始报告 IE 11 在使用该应用程序时随机“崩溃”。

我不确定崩溃一词是否准确描述了正在发生的事情。应用程序进入一个状态,元素将不再接受鼠标或键盘输入,也不会改变显示以显示悬停样式。但是,当您将鼠标悬停在按钮和输入元素上时,光标图像会相应地发生变化,并且可以使用鼠标滚轮(但只能使用鼠标滚轮)滚动可滚动部分。

当应用程序处于这种状态时,我运行了 UI Responsiveness Profiler,发现没有运行客户端脚本,只有 IE 的垃圾收集器。经过一周的测试,我终于确定,当用户单击使用 svg 元素生成的图标时触发状态,但仅当单击触发从 DOM 中删除单击的 svg 元素的函数时。

这是一个有助于解释/重现问题的代码笔: http://codepen.io/GooeyIdeas/pen/WvpPzP

以及娱乐的最低标准:

// This is a simple *viewmodel* - javascript that defines the data and behavior of your UI
function AppViewModel() 
    var self = this;
    this.isLocked = ko.observable(false);
    this.toggleLock = function()
      self.isLocked(!self.isLocked.peek())
    


ko.applyBindings(new AppViewModel());
svg use
  cursor: crosshair;

svg
  border: 1px solid #eeeeee;
  cursor: default;

svg:hover
  border-color: #dedede;
  background: #cecece;

#svg-icons
  display: none;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>The cursor will change into a crosshair if you are hovering over the correct element.</div>
<div>
  <!-- ko if: isLocked    -->
  <svg class="ux-icon-svg"  ><use data-bind="click: toggleLock" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#locked"></use></svg>
  <!-- /ko -->
  <!-- ko ifnot: isLocked -->
  <svg class="ux-icon-svg"  ><use data-bind="click: toggleLock" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#unlocked"></use></svg>
  <!--/ko-->
</div>

<svg xmlns="http://www.w3.org/2000/svg" id="svg-icons">
  <symbol viewBox="0 0 24 24" id="unlocked">
    <path d="M18,9h-1V7c0-2.8-2.2-5-5-5S7,4.2,7,7h1.9c0-1.7,1.4-3.1,3.1-3.1s3.1,1.4,3.1,3.1v2H6c-1.1,0-2,0.9-2,2v9c0,1.1,0.9,2,2,2
             h12c1.1,0,2-0.9,2-2v-9C20,9.9,19.1,9,18,9z"></path>
  </symbol>
  <symbol viewBox="0 0 24 24" id="locked">
    <path d="M18,9h-1V7c0-2.8-2.2-5-5-5S7,4.2,7,7v2H6c-1.1,0-2,0.9-2,2v9c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-9C20,9.9,19.1,9,18,9z
             M15.1,9H8.9V7c0-1.7,1.4-3.1,3.1-3.1s3.1,1.4,3.1,3.1V9z"></path>
  </symbol>
</svg>

有没有人遇到过这种情况?有谁知道仍然可以让我使用 SVG 'use' 元素的解决方法?我需要澄清什么吗?

*编辑 似乎有些人无法重现此错误。我想知道是否有其他人可以重现此错误,如果不能,您运行的是哪个版本的 Windows?

**编辑 看起来这个错误在 Windows 8 PC 上不存在。为了确保我在示例中添加了 CSS,当您将鼠标悬停在 svg use 元素上时,它会将光标变为十字准线,因为您必须单击该元素才能触发崩溃。

【问题讨论】:

似乎有些人无法重现此错误。我想知道是否有其他人可以重现此错误,如果不能,您运行的是哪个版本的 Windows? 我无法从小提琴中重现该问题,在 win server 8.1 IE11 中运行 Windows 8 PC 上似乎不存在此错误。我在示例中添加了 CSS,当您将鼠标悬停在 svg use 元素上时,它会将光标变为十字准线,因为您必须单击该元素才能触发崩溃。只是为了确保我们不会错过点击 你用的是什么win机器? 我现在可以在我的 win 7 机器上确认该错误,以为我最初没有 IE 11。但就解决方法而言,我不知道。假设您必须使用 ,为什么不创建两个不同的 svg 图标并手动切换?这并不理想,但它会阻止问题停止页面的其余部分 【参考方案1】:

由于这篇文章没有太多流量,我想我会发布一个解决方案: 我添加了这个 CSS 规则:

svg use 
  pointer-events: none;

这并不理想,但它可以防止 IE 11 被锁定,这就是我支持这个项目所需要的全部。但是,我希望这篇文章可以帮助将来可能遇到此错误并确实需要支持旧版本 IE 的其他人。如果有人愿意花时间提出一个更强大的解决方案,我会接受它作为这篇文章的答案。

我还应该就这个问题向微软提交错误报告吗?

【讨论】:

嗨。只是为了让您知道,我已经在两台不同的 PC 上进行了测试,并且还请其他几个人也进行了尝试。我们没有人能够重现您描述的问题。鉴于您为诊断和描述它所花费的时间,显然存在一个问题,但我只能猜测您还没有提到更多的东西。我建议在MS Connect 上提交一个错误,并包含一个附加到错误的选项卡内容进程的挂起转储(私下)。 澄清一下:您使用的是 codepen 站点还是 min 标记进行测试?另外,你测试的是什么版本的windows?我们正在运行 64 位 Windows 7,我们的质量团队发现 IE 11 的问题在不同的操作系统上呈现不同,也许这是其中之一? 我刚刚在我的办公室测试了 10 台不同的 PC,并且能够在所有这些 PC 上重现“崩溃”。我运行的是 Internet Explorer 11(无附加组件)。 这似乎很有可能。我确实更新了小提琴和 sn-p 以确保它正在被正确测试。不知道为什么不考虑将点击绑定放在使用元素上...如果您不介意仔细检查更新的示例,我将不胜感激! 微软会停止开发 IE/edge 来帮助世界!我生命中这么多时间......感谢您的解决方案!【参考方案2】:

我遇到了这个问题,&lt;svg&gt; 是使用 AngularJS 和 ng-if 从 DOM 中动态添加或删除的。接受的解决方案对我不起作用。可行的解决方案是使用 ng-show 代替它隐藏和显示 SVG,而不是在 DOM 中添加和删除它。

【讨论】:

幸运的是,您显然不需要使用“ng-if”来隐藏您的 SVG 元素。有时它很有用,因为它实际上删除了隐藏的标记并允许某些 CSS 规则正常工作。如果是这种情况,我建议使用“dynamic-svg-wrapper”类将 SVG 元素包装在“div”或“span”标签中。将触发切换 SVG 图标显示的事件分配给包装器元素。然后创建这个 CSS 规则:'.dynamic-svg-wrapper svg pointer-events: none;' 您能否使用您正在使用的图标更新您的答案,该图标也导致此错误但不适用于 css 修复?

以上是关于使用动态 SVG 元素时 IE 11 “崩溃”的主要内容,如果未能解决你的问题,请参考以下文章

IE 11 SVG 动画平滑度

SVG用作通知的小图标时崩溃

CSS IE 悬停效果 - 重叠元素、显示:块和崩溃

释放动态数组初始化时程序崩溃

IE浏览器经常性崩溃是啥原因?

删除动态数组时崩溃