Detect when embedded svg is loaded with Angular
up vote
0
down vote
favorite
I've been struggling a long time with this, lots of older posts address the issue but in incomplete, indirect or obsolete ways. Its such a common issue, a common solution would be ideal. I cannot/should-not modify the SVG. The svg has an id and all the various groups have ids that I need to interact with.
The issue is that I can't assign a load event to the svg element itself because it isn't loaded yet when my controller runs; And if I assign the on load event to the parent embed tag, well, then I can't access the elements via getElementByID because they aren't loaded yet either.
View:
<div style="width:1000px" ng-controller="Controller">
<embed id="svgObject" width="100%" height="100%" ng-src="{{modelSVG}}" type="image/svg+xml"></embed>
</div>
Controller:
.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
})
}])
Another attempt to get at the actual svg document
var svgDocument = svgObject.contentDocument ? svgObject.contentDocument : svgObject.contentWindow.document;
I can't believe this is so difficult.
javascript angularjs svg embed onload
add a comment |
up vote
0
down vote
favorite
I've been struggling a long time with this, lots of older posts address the issue but in incomplete, indirect or obsolete ways. Its such a common issue, a common solution would be ideal. I cannot/should-not modify the SVG. The svg has an id and all the various groups have ids that I need to interact with.
The issue is that I can't assign a load event to the svg element itself because it isn't loaded yet when my controller runs; And if I assign the on load event to the parent embed tag, well, then I can't access the elements via getElementByID because they aren't loaded yet either.
View:
<div style="width:1000px" ng-controller="Controller">
<embed id="svgObject" width="100%" height="100%" ng-src="{{modelSVG}}" type="image/svg+xml"></embed>
</div>
Controller:
.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
})
}])
Another attempt to get at the actual svg document
var svgDocument = svgObject.contentDocument ? svgObject.contentDocument : svgObject.contentWindow.document;
I can't believe this is so difficult.
javascript angularjs svg embed onload
With the AngularJS framework use a custom directive or use the new ng-on directive to attach an event handler to an element.
– georgeawg
Nov 21 at 23:34
Tried equivalent solutions, will not work. ng-on-load isn't different than onload and would have to go on the svg object inside the svg file; but the file cannot be modified. As far as I can tell, a custom directive wouldn't be able to tell be when the child directive, the svg document, is fully loaded by the browser .
– gunslingor
Nov 21 at 23:49
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I've been struggling a long time with this, lots of older posts address the issue but in incomplete, indirect or obsolete ways. Its such a common issue, a common solution would be ideal. I cannot/should-not modify the SVG. The svg has an id and all the various groups have ids that I need to interact with.
The issue is that I can't assign a load event to the svg element itself because it isn't loaded yet when my controller runs; And if I assign the on load event to the parent embed tag, well, then I can't access the elements via getElementByID because they aren't loaded yet either.
View:
<div style="width:1000px" ng-controller="Controller">
<embed id="svgObject" width="100%" height="100%" ng-src="{{modelSVG}}" type="image/svg+xml"></embed>
</div>
Controller:
.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
})
}])
Another attempt to get at the actual svg document
var svgDocument = svgObject.contentDocument ? svgObject.contentDocument : svgObject.contentWindow.document;
I can't believe this is so difficult.
javascript angularjs svg embed onload
I've been struggling a long time with this, lots of older posts address the issue but in incomplete, indirect or obsolete ways. Its such a common issue, a common solution would be ideal. I cannot/should-not modify the SVG. The svg has an id and all the various groups have ids that I need to interact with.
The issue is that I can't assign a load event to the svg element itself because it isn't loaded yet when my controller runs; And if I assign the on load event to the parent embed tag, well, then I can't access the elements via getElementByID because they aren't loaded yet either.
View:
<div style="width:1000px" ng-controller="Controller">
<embed id="svgObject" width="100%" height="100%" ng-src="{{modelSVG}}" type="image/svg+xml"></embed>
</div>
Controller:
.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
})
}])
Another attempt to get at the actual svg document
var svgDocument = svgObject.contentDocument ? svgObject.contentDocument : svgObject.contentWindow.document;
I can't believe this is so difficult.
javascript angularjs svg embed onload
javascript angularjs svg embed onload
edited Nov 21 at 21:34
asked Nov 21 at 20:17
gunslingor
446313
446313
With the AngularJS framework use a custom directive or use the new ng-on directive to attach an event handler to an element.
– georgeawg
Nov 21 at 23:34
Tried equivalent solutions, will not work. ng-on-load isn't different than onload and would have to go on the svg object inside the svg file; but the file cannot be modified. As far as I can tell, a custom directive wouldn't be able to tell be when the child directive, the svg document, is fully loaded by the browser .
– gunslingor
Nov 21 at 23:49
add a comment |
With the AngularJS framework use a custom directive or use the new ng-on directive to attach an event handler to an element.
– georgeawg
Nov 21 at 23:34
Tried equivalent solutions, will not work. ng-on-load isn't different than onload and would have to go on the svg object inside the svg file; but the file cannot be modified. As far as I can tell, a custom directive wouldn't be able to tell be when the child directive, the svg document, is fully loaded by the browser .
– gunslingor
Nov 21 at 23:49
With the AngularJS framework use a custom directive or use the new ng-on directive to attach an event handler to an element.
– georgeawg
Nov 21 at 23:34
With the AngularJS framework use a custom directive or use the new ng-on directive to attach an event handler to an element.
– georgeawg
Nov 21 at 23:34
Tried equivalent solutions, will not work. ng-on-load isn't different than onload and would have to go on the svg object inside the svg file; but the file cannot be modified. As far as I can tell, a custom directive wouldn't be able to tell be when the child directive, the svg document, is fully loaded by the browser .
– gunslingor
Nov 21 at 23:49
Tried equivalent solutions, will not work. ng-on-load isn't different than onload and would have to go on the svg object inside the svg file; but the file cannot be modified. As far as I can tell, a custom directive wouldn't be able to tell be when the child directive, the svg document, is fully loaded by the browser .
– gunslingor
Nov 21 at 23:49
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
This is by far the prettiest and best solution I found that doesn't require much code. In essence, we GET the svg file and parse it as a document fragment so everything is added to the DOM (apparently and magically), then we assign the result back to the original div and can then access the svg directive by id.
View:
<div style="width:1000px" ng-controller="Controller">
<div id="svgObject" style="width: 600px; height: 600px;"></div>
</div>
Controller:
.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);
});
The Magic Function:
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;
}
Approach was discovered here: jquery's append not working with svg element?
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
This is by far the prettiest and best solution I found that doesn't require much code. In essence, we GET the svg file and parse it as a document fragment so everything is added to the DOM (apparently and magically), then we assign the result back to the original div and can then access the svg directive by id.
View:
<div style="width:1000px" ng-controller="Controller">
<div id="svgObject" style="width: 600px; height: 600px;"></div>
</div>
Controller:
.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);
});
The Magic Function:
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;
}
Approach was discovered here: jquery's append not working with svg element?
add a comment |
up vote
0
down vote
This is by far the prettiest and best solution I found that doesn't require much code. In essence, we GET the svg file and parse it as a document fragment so everything is added to the DOM (apparently and magically), then we assign the result back to the original div and can then access the svg directive by id.
View:
<div style="width:1000px" ng-controller="Controller">
<div id="svgObject" style="width: 600px; height: 600px;"></div>
</div>
Controller:
.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);
});
The Magic Function:
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;
}
Approach was discovered here: jquery's append not working with svg element?
add a comment |
up vote
0
down vote
up vote
0
down vote
This is by far the prettiest and best solution I found that doesn't require much code. In essence, we GET the svg file and parse it as a document fragment so everything is added to the DOM (apparently and magically), then we assign the result back to the original div and can then access the svg directive by id.
View:
<div style="width:1000px" ng-controller="Controller">
<div id="svgObject" style="width: 600px; height: 600px;"></div>
</div>
Controller:
.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);
});
The Magic Function:
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;
}
Approach was discovered here: jquery's append not working with svg element?
This is by far the prettiest and best solution I found that doesn't require much code. In essence, we GET the svg file and parse it as a document fragment so everything is added to the DOM (apparently and magically), then we assign the result back to the original div and can then access the svg directive by id.
View:
<div style="width:1000px" ng-controller="Controller">
<div id="svgObject" style="width: 600px; height: 600px;"></div>
</div>
Controller:
.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);
});
The Magic Function:
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;
}
Approach was discovered here: jquery's append not working with svg element?
answered Nov 22 at 3:55
gunslingor
446313
446313
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419873%2fdetect-when-embedded-svg-is-loaded-with-angular%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
With the AngularJS framework use a custom directive or use the new ng-on directive to attach an event handler to an element.
– georgeawg
Nov 21 at 23:34
Tried equivalent solutions, will not work. ng-on-load isn't different than onload and would have to go on the svg object inside the svg file; but the file cannot be modified. As far as I can tell, a custom directive wouldn't be able to tell be when the child directive, the svg document, is fully loaded by the browser .
– gunslingor
Nov 21 at 23:49