如何使用 JavaScript 在 <object> 标记内选择 SVG 元素?
Posted
技术标签:
【中文标题】如何使用 JavaScript 在 <object> 标记内选择 SVG 元素?【英文标题】:How to select an SVG element inside an <object> tag with JavaScript? 【发布时间】:2016-01-27 08:45:13 【问题描述】:在我的 Angular 应用程序中,我希望能够使用 javascript 或 Angular jqLite 选择 <object>
标记的嵌入 SVG 元素。
通常,要执行此操作,必须编写类似以下内容:
// Create <object> element of the SVG
var objElement = document.createElement('object');
objElement.setAttribute('type',"image/svg+xml");
// Assume $rootScope.b64 contains the base64 data of the SVG
objElement.setAttribute('data', $rootScope.b64);
// Append the <object> inside the DOM's body
angular.element(document.body).append(objElement);
console.log(objElement);
console.log(objElement.getSVGDocument());
console.log(objElement.contentDocument);
在我的控制台中,objElement
返回带有 <svg>
元素及其内容的完整 <object>
(假设 data 属性包含完整的 base64 数据字符串 (b64))。
<object id="svgObject" data="b64" type="image/svg+xml">
#document
<svg>
</svg>
</object>
但是,getSVGDocument()
返回 null
和 contentDocument
返回
#document
<html>
<head></head>
<body></body>
<html>
为什么我无法检索 SVG 元素?如何正确获取 SVG 元素?我已经查看了很多文章,但我无法获得 <svg>
元素。这可能与跨域政策有关吗?
【问题讨论】:
在访问其内容之前,您需要等待对象的 onload 事件触发。 如果我将getSVGDocument()
包含在 onload 事件中,我会得到 Uncaught SecurityError: Failed to execute 'getSVGDocument' on 'HTMLObjectElement': Blocked a frame with origin "http://127.0.0.1:8080" from accessing a frame with origin "null". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "data". Protocols must match.
这是 Chrome 吗?我想你被它的安全模型阻止了。您可以尝试不同的 UA
是的,我正在 Chrome 上开发。你的意思是用户代理?如何切换其安全模型?
Robert 的意思是尝试不同的浏览器,比如 Firefox。 Chrome 具有更严格的安全模型。例如,如果您使用file://
URL,它会禁止某些事情。
【参考方案1】:
您看不到该对象的原因是您很可能在 DOM 加载之前对其进行探测。试试:
// Create <object> element of the SVG
var objElement = document.createElement('object');
objElement.setAttribute('type',"image/svg+xml");
// Assume $rootScope.b64 contains the base64 data of the SVG
objElement.setAttribute('data', $rootScope.b64);
// Append the <object> inside the DOM's body
angular.element(document.body).append(objElement);
objElement.addEventListener('load', doStuff);
function doStuff()
console.log(objElement);
var svgDoc = getSVGDoc(objElement);
console.log('svgDoc', svgDoc);
function getSVGDoc(element)
console.log('getting obj');
try
return element.contentDocument;
catch (e)
try
return element.getSVGDocument();
catch (e)
console.log('SVG unsupported within this browser');
【讨论】:
【参考方案2】:即使 SVG 已明确加载到 DOM 中,我也无法使用 document.querySelector("svg")
之类的东西选择 SVG。原来我需要这样做:
var obj = document.querySelector("object");
var svg = obj.contentDocument.querySelector("svg");
显然主文档和该子文档之间存在界限,您必须使用contentDocument
来弥合分歧。
【讨论】:
这对我不起作用。我很容易获得object
,但随后.contentDocument
返回null,即使我可以在Chrome devtools Elements 和Console 窗口的对象下清楚地看到#document
。【参考方案3】:
似乎 getSVGDocument() 已被弃用。你试过document.querySelector('object svg')
之类的吗?
【讨论】:
以上是关于如何使用 JavaScript 在 <object> 标记内选择 SVG 元素?的主要内容,如果未能解决你的问题,请参考以下文章
在javascript中如何判断一个变量为空或者undefine