在包含SVG标记元素的页面上使用基本标记无法呈现标记
尝试在基于SVG的可视化中使用SVG标记元素时遇到问题。 我将我的更改添加到每个页面上都包含基本标记的Web应用程序,以便任何对CSS文件,JavaScript文件等的引用都可以是相对的。
我有一些示例代码重现了这个问题。 有一个线元素和一个标记元素定义。 标记元素通过标记的uri和id在其“marker-end”属性中被引用。 没有基地标签,箭头显示正常。 用基本标签,它没有被显示。 原因是因为base标签改变了浏览器parsingurls的方式。即使对于line的marker-end属性中指定的简单的基于id的URL也是如此。
有什么办法可以避免这个问题,而不必删除基地标签?
我真的不能删除它,因为它的使用是相当根深蒂固的产品即时通讯工作。 我需要为我的web应用程序支持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>
HTML <base>
元素用于说“parsing所有相对的URL而不是相对于这个页面,而是到一个新的位置”。 在你的情况,你已经告诉它相对于HTML页面的目录。
SVG marker-mid="url(…)"
属性是一个FuncIRI参考 。 当你使用像url(#foo)
这样的值时,相对IRI通常是相对于当前页面被parsing的,find具有foo
id的元素。 但是,当你使用<base>
,你改变它的外观。
要解决这个问题,请使用更好的值。 由于您的基础引用是当前目录,因此您可以简单地使用当前文件的名称:
<line … marker-mid="url(this_page_name.html#arrow)" />
如果你有一个不同的<base>
href,比你所显示的,如:
<base href="http://other.site.com/whee/" />
那么你将需要使用绝对的href,例如
<line … marker-mid="url(http://my.site.com/this_page_name.html#arrow)" />
尝试使用javascript:
<line id="something" />
与本地:
document.getElementById('something').setAttribute('marker-mid', 'url(' + location.href + '#arrow)');
使用jQuery:
$('#something').attr('marker-mid', 'url(' + location.href + '#arrow)');
它只是工作。
在丰富的Web应用程序(如Angular构build的应用程序)的上下文中,需要设置<base>
标记以使HTML5风格的导航工作,可能会变得麻烦,试图以永久方式解决这个问题。
就我而言,我正在开发的应用程序展示了一个基于SVG的交互式图表构build器 ,它将改变应用程序的URL,因为我select了其中的元素。
我所做的是添加一个全局事件处理程序,它将修复页面中find的任何<path>
元素中的所有url(#...)
内联样式:
$rootScope.$on 'fixSVGReference', -> $('path').each -> $path = $ this if (style = $path.attr 'style')? $path.attr 'style', style.replace /url\([^)#]*#/g, "url(#{location.href}\#"
然后在关键的地方触发这个处理程序,比如当应用程序状态发生变化时(我正在使用ui-router )
$rootScope.$on '$stateChangeSuccess', -> $timeout (-> $rootScope.$emit 'fixSVGReference'), 5
以及我知道的任何地方都会有新的/更新的path。 在这里, $timeout
事件是为了说明在触发$stateChangeSuccess
事件之后的某个时刻,DOM节点实际上是asynchronous更改的。
在Angular 2+中,可以在应用程序模块中注入基本path,而不是使用<base>标记。 这为我解决了Edge和Firefox的问题。
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
如果你不想修改/animationsvg,比改变url()参数更简单。
包括svg为图像:
<img src="yourpath/image.svg">
Ember 2.7将用rootURL
replace<base>
标签, rootURL
解决这个问题。
同时在我的d3渐变我使用以下内容:
.attr('fill', `url(${Ember.$(location).attr('href')}#my-gradient)`);
如果你不这样做,你的目标项目将是透明的。
在当前(04-2017)的Windows上,所有浏览器的行为与预期相同( mask = url(“#svgmask”) )。 Chrome,火狐,甚至IE 11! – 但边缘出现了一个错误。
因此,对于Microsoft Edge,当您在文档中使用基本标记时,仍然需要为掩码ID提供绝对path( mask =“url(path / to / this-document.htm#svgmask)” )
<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>
- 如何在“–allow-file-access-from-files”模式下使用Chrome启动HTML?
- 如何更改chrome封装的应用程序ID或者为什么我们需要manifest.json中的关键字段?
- 别名为chrome console.log
- Chrome扩展程序hint.js&ngHintModules
- 如何保存Chrome开发人员工具的样式面板的CSS更改?
- Google Plusbutton代码在Chrome中警告:“不安全的JavaScript尝试访问框架”
- chrome:如何closures用户代理样式表设置?
- 使用Chrome,如何find事件绑定到哪些元素?
- Chrome开发工具:如何跟踪networking的链接,打开一个新的标签?