Using base tag on a page that contains SVG marker elements fails to render marker

你离开我真会死。 提交于 2019-11-26 16:15:39
Phrogz

The HTML <base> element is used to say "resolve all relative URLs relative not to this page, but to a new location". In your case, you've told it to resolve relative to the directory with the HTML page.

The SVG marker-mid="url(…)" attribute is a FuncIRI Reference. When you use a value like url(#foo) that relative IRI is normally resolved relative to the current page, finding the element with the foo id. But, when you use <base>, you change where it looks.

To solve this problem, use a better value. Since your base reference is the current directory, you can simply use the name of the current file:

<line … marker-mid="url(this_page_name.html#arrow)" />

If you have a different <base> href, than what you've shown, like:

<base href="http://other.site.com/whee/" />

then you will need to use an absolute href, e.g.

<line … marker-mid="url(http://my.site.com/this_page_name.html#arrow)" />

In the context of a rich web app like one built on Angular, where you need to set the <base> tag to make HTML5-style navigation work, it can get messy to try to fix that in a permanent way.

In my case, the app I was working on was showing a SVG-based interactive diagram builder that would change the app url as I selected elements therein.

What I did was to add a global event handler that would fix all url(#...) inline styles in any <path> element found in the page:

$rootScope.$on 'fixSVGReference', ->
    $('path').each ->
        $path = $ this
        if (style = $path.attr 'style')?
            $path.attr 'style', style.replace /url\([^)#]*#/g, "url(#{location.href}\#"

Then trigger this handler in key places, like when the app state changes (I'm using ui-router)

$rootScope.$on '$stateChangeSuccess', ->
    $timeout (-> $rootScope.$emit 'fixSVGReference'), 5

As well as anywhere where I know there'd be new/updated paths like these. Here, the $timeout thing is to account for the fact that the DOM nodes really are changed asynchronously sometime after the $stateChangeSuccess event is triggered.

Try with javascript:

<line id="something" />

With native:

document.getElementById('something').setAttribute('marker-mid', 'url(' + location.href + '#arrow)');

With jQuery:

$('#something').attr('marker-mid', 'url(' + location.href + '#arrow)');

It just works.

In Angular 2+, you can inject the base path in your app module instead of using the <base> tag. This resolved the issue in Edge and Firefox for me.

import { APP_BASE_HREF } from '@angular/common';

@NgModule({
   providers: [{
     provide: APP_BASE_HREF,
     useValue: '/'
   }]
})
export class AppModule { }

https://angular.io/docs/ts/latest/api/common/index/APP_BASE_HREF-let.html

Ember 2.7 will replace the <base> tag with rootURL which should fix this issue.

In the meantime in my d3 for gradients I'm using the following:

.attr('fill', `url(${Ember.$(location).attr('href')}#my-gradient)`);

If you don't do this, the item you are targeting will seem to be transparent.

On Windows currently (04-2017) all Browsers behave as expected ( mask=url("#svgmask") ). Chrome, Firefox, even IE 11!! - but Edge comes up with an error.

So for Microsoft Edge you still need to give the absolute path ( mask="url(path/to/this-document.htm#svgmask)" ) for your mask ID´s when you are using a base tag in your document:

<svg viewBox="0 0 600 600" >
  <defs>
    <mask id="svgmask">
      <image width="100%" height="100%" xlink:href="path/to/mask.svg" ></image> 
    </mask>
  </defs>
  <image mask="url(path/to/this-document.htm#svgmask)" width="600" height="600" xlink:href="path/to/image.jpg"></image>
</svg>
maechler

If you do not want want to modify / animate the svg there is a simpler solution than changing the url() parameter.

Include the svg as image:

<img src="yourpath/image.svg">

You can archive it with:

$("[marker-mid]").attr("marker-mid", function () {
    return $(this).attr("marker-mid").replace("url(", "url(" + location.href); 
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!