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

时间:2015-06-04 20:28:24

标签: javascript html svg knockout.js internet-explorer-11

我最近为我公司的新html应用程序实现了一个自定义SVG Icon控件。不久它实施后,我们的质量部门开始报告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" width="24" height="24"><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" width="24" height="24"><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'使用'元素?我需要澄清什么吗?

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

**编辑 看起来这个bug在Windows 8 PC上不存在。为了确保我将CSS添加到我的示例中,当您将鼠标悬停在svg use元素上时,会将光标更改为十字准线,因为这是您必须单击以触发崩溃的元素。

2 个答案:

答案 0 :(得分:44)

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

svg use {
  pointer-events: none;
}

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

我是否应该向微软提交有关此问题的错误报告?

答案 1 :(得分:0)

我遇到了<svg>,使用AngularJS和ng-if动态添加或删除了DOM。接受的解决方案对我不起作用。确实有效的解决方案是使用ng-show来隐藏和显示SVG,而不是从DOM中添加和删除它。