SVG 'use' tag in Chrome broken

后端 未结 2 2037
攒了一身酷
攒了一身酷 2021-02-20 06:17

There is SAP (AngularJS and Angular Route) with icon-based navigation made by svg-sprite. So, I hava inline code like this:

相关标签:
2条回答
  • 2021-02-20 07:01

    This is caused by a combination of AngularJS' dependency of <base href="/" /> and UI routing, when the application is not at its "root" state, the relative hash link in the <use> element would not correctly resolve.

    To get around this, you would need to resolve the xlink:href to use absolute path. You may do the following:

    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, '');
            }
        });
    
    0 讨论(0)
  • 2021-02-20 07:04

    I was experiencing really similar issue to what you describe with a difference that I would generate my icons <svg> and <use> in a directive.

    I have been looking for an answer for a better part of today and came up with a workaround to the <use> and xlink:href question. Which simply recreates the functionality by inlining the wanted svg.

    For the sake of simplicity let's say i have <angular-icon> directive that receives the name of the icon by an attribute icon-name

    <angular-icon icon-name="{{someObject.iconName}}">

    working directive now looks as follows:

    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: '@'
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题