在包含SVG标记元素的页面上使用基本标记无法呈现标记

DaV*_*ViS 46 html firefox svg google-chrome base-url

尝试在基于SVG的可视化中使用SVG标记元素时遇到了问题.我正在将我的更改添加到Web应用程序中,该应用程序恰好在每个页面上都包含一个基本标记,因此对CSS文件,javascript文件等的任何引用都可以是相对的.

我在下面有一些示例代码可以重现该问题.有一个line元素,并定义了一个标记元素.标记元素由其"marker-end"属性中的行引用,通过uri和id of marker.没有基本标签,箭头显示正常.使用基本标记时,未显示.原因是因为基本标记改变了浏览器解析URL的方式..即使是在行的marker-end属性中指定的基于简单id的url.

有没有办法解决这个问题而不必删除基本标签?

我无法真正删除它,因为它的使用在我正在研究的产品中相当根深蒂固.我需要为我的webapp支持Firefox,Chrome和IE9 +.Firefox和Chrome都会产生这个问题.IE工作正常(即箭头标记显示).

<html>
    <head>
    <base href=".">
    <style>
    .link { stroke: #999; stroke-opacity: .6; }
    marker#arrow { fill: black; }
    </style>
</head>
<body>
    <svg width="100%" height="100%">
        <defs>
            <marker id="arrow" viewBox="0 -5 10 10" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto">
                <path d="M0,-5L10,0L0,5"></path>
            </marker>
        </defs>
        <line x1="100" y1="100" x2="333" y2="333" marker-start="url(#arrow)" class="link"></line>
    </svg>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Phr*_*ogz 48

HTML <base>元素用于表示"解析所有相对URL,而不是相对于此页面,而是解析到新位置".在您的情况下,您已告诉它使用HTML页面相对于目录进行解析.

SVG marker-mid="url(…)"属性是FuncIRI Reference.当您使用类似于url(#foo)相对值的值时,通常会相对于当前页面解析IRI,找到具有fooid 的元素.但是,当您使用时<base>,您会改变它的外观.

要解决此问题,请使用更好的值.由于您的基本引用是当前目录,因此您只需使用当前文件的名称:

<line … marker-mid="url(this_page_name.html#arrow)" />
Run Code Online (Sandbox Code Playgroud)

如果你有一个不同于<base>你所显示的href,例如:

<base href="http://other.site.com/whee/" />
Run Code Online (Sandbox Code Playgroud)

那么你需要使用一个绝对的href,例如

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

  • Thanx非常感谢Phrogz的回复.我实际上昨天结束时已经弄明白了.由于我通过javascript添加标记,我只需使用以下设置marker-start,marker-end等属性值:"url("+ window.location +"#arrow)"需要注意的一点是通过设置带有绝对网址的标记属性,确实解决了Firefox和Chrome中的问题,但现在它在IE中无效.这不是什么大不了的事.我可以根据使用的浏览器使用不同的行为.再来一次.戴夫 (8认同)

nik*_*oza 5

尝试使用 javascript:

<line id="something" />
Run Code Online (Sandbox Code Playgroud)

与原生:

document.getElementById('something').setAttribute('marker-mid', 'url(' + location.href + '#arrow)');
Run Code Online (Sandbox Code Playgroud)

使用 jQuery:

$('#something').attr('marker-mid', 'url(' + location.href + '#arrow)');
Run Code Online (Sandbox Code Playgroud)

它只是有效。


mat*_*hat 5

在像Angular一样构建的富Web应用程序的上下文中,您需要设置<base>标记以使HTML5样式的导航工作,尝试以永久方式修复它可能会变得混乱.

在我的例子中,我正在处理的应用程序显示了一个基于SVG的交互式图表构建器,当我在其中选择元素时,它将更改应用程序URL.

我所做的是添加一个全局事件处理程序,它将修复页面中找到的url(#...)任何<path>元素中的所有内联样式:

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

然后在关键位置触发此处理程序,例如应用程序状态更改时(我正在使用ui-router)

$rootScope.$on '$stateChangeSuccess', ->
    $timeout (-> $rootScope.$emit 'fixSVGReference'), 5
Run Code Online (Sandbox Code Playgroud)

以及我所知道的任何地方都会有这样的新/更新路径.在这里,$timeout事情是要考虑到$stateChangeSuccess事件被触发后DOM节点确实异步更改的事实.


CTa*_*zon 5

在 Angular 2+ 中,您可以在应用模块中注入基本路径,而不是使用 <base> 标签。这为我解决了 Edge 和 Firefox 中的问题。

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

@NgModule({
   providers: [{
     provide: APP_BASE_HREF,
     useValue: '/'
   }]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

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