为什么IE渲染空SVG元素时会冻结布局?

时间:2014-08-12 21:54:37

标签: css internet-explorer svg internet-explorer-10 internet-explorer-11

我目前正在IE 10和11中遇到一个问题,其中浏览器标签时不时地悬挂在UI响应工具中的布局上。我是一个团队写一个相当大的knockout.js网络应用程序的一部分,因此确定创建此问题的确切条件非常困难。据我所知,当从页面中删除加载指示符HTML时,浏览器选项卡会在执行布局时挂起,并且某些div和一个空的SVG标记将附加到DOM的位置。

我已经能够确定空的SVG标签是罪魁祸首,但我不知道为什么我无法从页面中删除该标签它是否是D#的重要元素我正在尝试创建的数据可视化。

以下是IE 11为我提供的美国响应报告。我已经放大了有问题的区域,正如您在图片中看到的那样,布局线程使CPU达到100%。

enter image description here

在进入代码示例之前,我的问题是:

为什么浏览器标签会间歇地冻结/挂起以向页面添加空的SVG元素?

HTML通过javascript以尽可能少的方式附加到DOM中,以减少浏览器中的重排:

var contentHTML = "";
contentHTML += '<div class="axis-title y-axis-title">' + renderString(bindingData.yAxis.title) + "</div>";
contentHTML += '<div class="' + CANVAS_CLASS + '"></div>';
contentHTML += '<svg class="x-axis"></svg>'; // The problematic element

element.innerHTML = contentHTML;

这导致以下HTML(注意:所有数据绑定的东西都是针对knockout.js绑定处理程序,它触发上面的JS):

<div class="chart" data-bind="
barChart: {
    data: rowData,
    categoryTextKey: 'label',
    valueKey: 'keyOnObject',
    xAxis: {
        title: 'xAxisTitle',
        domain: [-1, 1]
    },
    yAxis: {
        title: 'yAxisTitle'
    },
    onClick: onLabelClick,
    formatValueText: formatPercentage
}
"></div>
    <div class="axis-title y-axis-title">Y Title</div>
    <div class="chart-canvas"></div>
    <svg xmlns="http://www.w3.org/2000/svg" class="x-axis" />
    <div class="axis-title x-axis-title">X Title</div>
</div>

最后,我还使用flexbox CSS规则来布局我的HTML。我不确定这是否会影响这个问题,但如果它有帮助,这里是CSS:

.chart {
    .flexbox();
    .flex-direction(column);
    height: 100%;
    width: 100%;

    .chart-label-click {
        cursor: pointer;
    }

    .chart-header,
    .axis-title,
    .x-axis {
        .flex-grow(0);
        .flex-shrink(0);
    }

    .chart-canvas {
        .flex-grow(1);
        .flex-shrink(1);

        overflow-x: hidden;
        overflow-y: auto;
        width: 100%;
    }

    .chart-canvas svg {
        display: block;
        width: 100%;
    }

    .axis-title {
        font-weight: bold;
    }

    .x-axis {
        .flexbox();
        .flex-grow(0);
        .flex-basis(20px);

        margin-bottom: 5px;
        overflow: visible;
        width: 100%;
    }

    .x-axis line,
    .x-axis path {
        fill: none;
        stroke: #d1d1d1;
        stroke-width: 1px;
        shape-rendering: crispEdges;
    }
}

感谢您的帮助。我不确定如何解决这个问题,因为它在我们的应用程序的一个部分中是间歇性的,并且我们的代码库非常大,可以找出其他文件中可能导致此问题的代码的确切组合。

4 个答案:

答案 0 :(得分:4)

所描述的问题似乎是这个错误: https://connect.microsoft.com/IE/feedback/details/796745/mouse-events-are-not-delivered-at-all-anymore-when-inside-an-svg-a-use-is-removed-from-the-dom

在评论中描述的解决方法至少对我们有用: 您必须在use元素上设置style="pointer-events: none;"。 或者只是将其添加到您的CSS:

svg use { pointer-events:none; }

但请注意,这也会禁用在use元素上触发的任何鼠标事件。

答案 1 :(得分:1)

确保您的代码没有使用JavaScript(或其他语言)设置值,甚至连引号都没有...

var a = ;//[var][space][a][space][=][space][;]

这将冻结IE11(不确定约10手)。

答案 2 :(得分:1)

我最终解决此问题的方法是删除display:flex元素上.chart的使用。在它的位置,我使用固定的高度和display:block。在将SVG和Flexbox混合在一起时,看起来这最终是一个错误。

答案 3 :(得分:0)

经过多天的搜索,我决定解决这个问题:

svg use { pointer-events:none; }