谷歌浏览器中SVG的'use'标签存在问题

11

有一个使用SVG Sprite制作的基于图标导航的SAP(AngularJS和Angular Route)。因此,我有类似以下的内联代码:

<div style="height: 0; width: 0; position: absolute; visibility: hidden">
<svg xmlns="http://www.w3.org/2000/svg">
    <symbol id="icon-grid-32" viewBox="0 0 32 32">
        <g stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" stroke-linejoin="round">
            <path d="M2 2h11v11H2zM19 2h11v11H19zM2 19h11v11H2zM19 19h11v11H19z"/>
        </g>
    </symbol>
</svg>
</div>

还有像这样的导航图标:

<a href=""><svg class="icon icon-32 outline black"><use xlink:href="#icon-grid-32"></use></svg></a>
我在这个导航中所看到的都是空的,<use> 元素的大小为0 × 0像素。我知道 Firefox 存在关于 xml:base 的 错误,但添加了 xml:base 也没有帮助我解决问题。您可以尝试使用这个示例:http://css.yoksel.ru/assets/demo/svg-in-firefox/svg-has-base.html 它可以在 Firefox、Safari 和其他浏览器中使用,但在 Chrome 49+ 中不行(48 版本没有这个问题)。

1
将问题报告给Chrome的错误跟踪器。 - Robert Longson
这里是Chrome的错误跟踪器链接,您可以提交您的错误:https://bugs.chromium.org/p/chromium/issues/list - Jonathan Marzullo
2个回答

5
这是由AngularJS对<base href="/" />和UI路由的依赖造成的,当应用程序不处于其“根”状态时,<use>元素中的相对哈希链接将无法正确解析。
为了避免这种情况,您需要解析xlink:href以使用绝对路径。 您可以执行以下操作: angular-icon-template.html
<svg class="c-icon" viewBox="0 0 32 32">
    <use xlink:href="" ng-attr-xlink:href="{{baseUrl + '#' + iconName}}" />
</svg>

angular-icon.js

angular.module('angularIcon', [])
    .directive('angularIcon', {
        templateUrl: 'angular-icon-template.html',
        scope: { iconName: '@' },
        controller: function($scope) {
            $scope.baseUrl = window.location.href.replace(window.location.hash, '');
        }
    });

1
我遇到了与您描述的问题非常相似的问题,不同之处在于我会在指令中生成我的图标<svg><use>
我一直在寻找一个更好的解决方案,今天大部分时间都在寻找答案,并想出了一个解决方案来解决<use>xlink:href的问题。这个解决方案通过将所需的SVG内联来重新创建功能。
为了简单起见,假设我有一个<angular-icon>指令,该指令通过属性icon-name接收图标的名称。
现在,工作指令如下所示:
angular.module('angularIcon', [])
.directive('angularIcon', IconDirective);

function IconDirective(){
    return{
        template:'',
        templateNamespace:'svg',

        link:function(scope, element, attributes){

            // my icon name comes from $http call so it doesnt exist when initialising the directive, 
            attributes.$observe( 'iconName', function(iconName){

                // let's grab the icon from the sprite
                var icon = angular.element( document.getElementById( iconName ) ); 
                // let's clone it so we can modify it if we want
                var iconClone = icon.clone();

                var namespace = "http://www.w3.org/2000/svg";

                // manually create the svg element and append the inlined icon as no other way worked
                var svg = document.createElementNS( namespace, 'svg' );
                svg.setAttribute( 'viewBox', '0 0 32 32' );
                svg.setAttribute( 'xml:space', 'preserve' );

                svg.appendChild( iconClone[0] );
                // let's add the newly created svg+icon to the directive's element
                element[0].appendChild( svg );

            });

        },
        scope:{
            iconName: '@'
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接