javascript - 检测何时使用 Angular 加载嵌入式 svg
问题描述
我为此苦苦挣扎了很长时间,许多较旧的帖子都以不完整、间接或过时的方式解决了这个问题。它是如此普遍的问题,一个共同的解决方案将是理想的。我不能/不应该修改 SVG。svg 有一个 id,所有不同的组都有我需要与之交互的 id。
问题是我无法将加载事件分配给 svg 元素本身,因为当我的控制器运行时它尚未加载;如果我将加载事件分配给父嵌入标签,那么我无法通过 getElementByID 访问元素,因为它们也尚未加载。
看法:
<div style="width:1000px" ng-controller="Controller">
<embed id="svgObject" width="100%" height="100%" ng-src="{{modelSVG}}" type="image/svg+xml"></embed>
</div>
控制器:
.controller('HomeController',['BaseController','$scope','$location',function (BaseController,scope,location) {
scope.modelSVG = location.protocol() + '://' + location.host() + '/svg/pic.svg';
var svgObject = document.getElementById("svgObject");
svgObject.addEventListener('load', function(){
var svgDocument = svgObject.contentDocument;
**Do lots of stuff to EACH and every shape loadeded (e.g. show/hide, set hover/click events, etc
})
}])
另一个尝试获取实际的 svg 文档
var svgDocument = svgObject.contentDocument ? svgObject.contentDocument : svgObject.contentWindow.document;
我不敢相信这这么难。
解决方案
这是迄今为止我发现的不需要太多代码的最漂亮和最好的解决方案。本质上,我们获取 svg 文件并将其解析为文档片段,因此所有内容都添加到 DOM(显然是神奇的),然后我们将结果分配回原始 div,然后可以通过 id 访问 svg 指令。
看法:
<div style="width:1000px" ng-controller="Controller">
<div id="svgObject" style="width: 600px; height: 600px;"></div>
</div>
控制器:
.controller('HomeController',['BaseController','$scope','$location',function (BaseController,scope,location) {
scope.modelSVG = location.protocol() + '://' + location.host() + '/svg/pic.svg';
http({
method : "GET",
url : scope.svgPath
}).then(function mySuccess(response) {
var svgObject = document.getElementById('svgObject');
svgObject.appendChild(parseSVG(response.data));
var svgDocument = document.getElementById("svgDocument");//the id of the actual svg tag.
//do anything to fully loaded svg
}, function myError(response) {
alert(response.statusText);
});
魔术功能:
function parseSVG(svg) {
var div= document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+svg+'</svg>';
var frag= document.createDocumentFragment();
while (div.firstChild.firstChild)
frag.appendChild(div.firstChild.firstChild);
return frag;
}
推荐阅读
- android - 如何在 android 架构组件中使用 RxJava 而不是 LiveData?
- php - ZF2 TableGateway 查询返回空结果集,适配器查询有效
- architecture - 处理微服务架构中的枚举
- c# - Aurelia 浏览器控制台错误 - POST 请求 - 对预检请求的响应未通过访问控制检查
- c# - 下拉列表未找到正确的值
- python - Python - 如何停止循环
- json - Ruby API 调用从复杂的 json 中获取数据
- selenium - 选择选项车梅赛德斯
- php - PHP Array - 删除空元素,仅获取填充字符串
- github - 通过指定多个 Id 获取 GitHub 问题列表