Update textures in X3DOM model dynamically - javascript

I am developing a Web 3D app and I produced some code in Javascript that implements the following tag to an external .html file with the model in it, within an iframe.
In the <appearance> element in the X3D code block of the external .html file:
<texture id="XXX" repeats="true" repeatt="true" url="" scale="true"
hidechildren="true">
<img src="" attr=".../BMW.jpg" style="display: none; visibility: hidden;">
</texture>
Javascript code that places the above code in the appropriate block in the iframe after I click on a button:
ogl = true;
function toggleTexture(){
if (!ogl) {
var t = document.createElement("Texture");
t.setAttribute("id", "XXX");
t.setAttribute("repeatS", "true");
t.setAttribute("repeatT", "true");
var imgElement = document.createElement("img");
imgElement.setAttribute("src", "../HomeFurniture/assets/BMW.jpg");
t.appendChild(imgElement);
var iframe = document.getElementById("frame");
var innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
innerDoc.getElementById("anApp").appendChild(t);
innderDoc.x3dom.reload();
} else {
var iframe = document.getElementById("frame");
var innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
var ot = innerDoc.getElementById("anApp");
ot.removeChild(innerDoc.getElementById('XXX'));
}
return false;
}
The result in the debugging of Chrome browser shows that the piece of code needed is inserted, but the actual model is not updated with the appropriate texture.
There must be something that I miss, but I cannot find the solution. Any help would be appreciated.

FIXED: The problem was Google Chrome. I tested the Web app in Mozilla Firefox and everything works :)
Additionally, I tried the Javascript code in the child html file and it works in Chrome. It just refuses to work when the parent html file load the child html file within an iframe block.

Related

Encoded URI doesn't work like the src attribute for iframe in IE11

I try to generate src attribute for the iframe on the fly doing this:
var iframe = document.createElement('iframe');
var html = '<html> <head></head> <body></body> </html>';
var eventListener = '<script>window.addEventListener("message", someListenerFunction)</script>';
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html) + encodeURI(eventListener);
iframe.sandbox = 'allow-scripts';
This actually works fine in chrome/firefox/safari, but it doesn't work with ie11. Inside the iframe window it returns:
Cannot display the webpage
And in the console I get the error:
SCRIPT5: Access is denied.
File: unknowprotocol.htm, Line:1, Column:1
The problem I think in the encoded URI address.
The reason I do this - I need to generate lots of iframes and I don't want to create a static webpages for each of them.
Hope for your help. Thank you in advance.

Loading strategy of client side rendered html resources for html5 game

I am working on an HTML5 facebook game (inside facebook canvas iframe) in which I use jquery in addition to some other js files, css files (image files, in the css files), font files, sound files and screens (html divs in seperate files).
I want to have a loading script as the size of the resources is around 1 MB. There are two options;
first one is writing a resource loader and load everything in correct order which really is painful.
second one is first having a simple loading screen at startup, which will be quicly loaded, upon loading this page, starting to load the actual html (with js, css and everyting) and handing over the loading process to the browser client.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function iframeIsLoaded()
{
...
}
</script>
</head>
<body>
<div id="loadingScreen" class="..."> <!-- iframe will be under this div -->
...
</div>
<iframe ...>
</iframe>
...
obviously second option is much better but I don't have a clue how to do it. As shown above, I may use an iframe under the loading screen div but is there a way to send a message to the upper div from the iframe?
I am also open to other solutions!
You can do this using the iframe.load event.
What you will want to do is hide the iframe on page load and show the loading screen, then you want to wait until the content is loaded then Show the frame and hide the Loading screen.
(This example assumes you are using the src attribute of the IFrame to load the content)
Pure Javascript : Example JSFiddle
var frame = document.getElementById('iframeID');
var loading = document.getElementById('loadingScreen');
frame.style.display = 'none';//Originally hide the frame
loading.style.display = 'block';//Originally show the Loading Screen
frame.src = 'http://www.bing.com';//Set the src attribute
frame.onload = function() {
frame.style.display = 'block';//Show the frame after it is loaded
loading.style.display = 'none';//Hide the loading screen
}
EDIT : (Removed jQuery Example and Added a new Example based on Comment)
Here is a new example that checks the child page for the variable done to check if it is set to true.
Warning this example has the potential to not work due to Cross-Domain Scripting Security, this should only be used if you are 100% that both pages are on the same Domain
Child Page :
var done = false;
setTimeout(function () {
done = true;
}, 10000);
Parent Page : (Script needs placing after the HTML / Before the end of the Body Tag ())
<div>
<div id="loading">
Loading...
</div>
<iframe id="iframeID"></iframe>
</div>
<script type="text/javascript">
var frame = document.getElementById('iframeID');
var loading = document.getElementById('loading');
frame.style.display = 'none'; //Originally hide the frame
loading.style.display = 'block'; //Originally show the Loading Screen
frame.src = 'Test2.aspx'; //Set the src attribute
frame.onload = function () {
console.log('Loaded Frame');
}
var $interval = setInterval(CheckFrameDone, 500);
function CheckFrameDone() {
var done = frame.contentWindow.done;
console.log(done);
if (done) {
console.log('Frame is Finished Loading');
frame.style.display = 'block';
loading.style.display = 'none';
clearInterval($interval);
} else {
console.log('Still Waiting...');
}
}
</script>
With the second example you will notice that every 500 Milliseconds the parent page will check the child page for the done value, if it is true it will show the frame and clear the interval. Otherwise it will just continue to check.

Can't access canvas element in iframe

I got a iframe and I want to select a canvas element in this iframe. But it doesn't work. I'm using the following code.
This is my iframe
<body>
<div id="canvasdiv" width="300" height="300"></div>
</body>
This is my parent page
<iframe name="iframe" id="iframe" frameborder="0" width="325" height="325" src="..."></iframe>
With javascript I add a canvas with some properties. For example the id.
canvas.node.id = "canvas";
In my parent page I got the following javascript.
var iframe = document.getElementById("iframe");
alert(iframe);
var iframe_canvas = iframe.contentDocument || iframe.contentWindow.document;
alert(iframe_canvas);
var canvas = iframe_canvas.getElementById("canvas");
alert(canvas);
Result:
iframe = iframe element
iframe_canvas = html element
canvas = null
Does somebody know why I can't access the canvas element? =(
I'm sorry, but I solved the problem. Thanks for all the replies. =)
To test the getElementById function I called it by $(document).ready. But at this time the iframe wasn't rendered by the browser. That's why I could access the iframe it self but not the elements of the iframe. Now I assigned the function to a button and it works.
According to your HTML, this line of code:
var canvas = iframe_canvas.getElementById("canvas");
should be this to target the proper id value in your div:
var canvas = iframe_canvas.getElementById("canvasdiv");
You're omitting the code that adds the <canvas> element itself. Are you sure its id is canvas?
If you are, then you might be running into same-origin policy problems regarding accessing contents of iframes.
your code is fine expect for one part.
replace
getElementById("canvas")
with
getElementById("canvasdiv");

Javascript dynamic creation of iframe doesn't load src

I have the following piece of code that should dynamically load an iframe with the Google homepage as an example. The iframe gets created but the src is not loaded:
var theIframe2 = document.createElement("iframe");
theIframe2.setAttribute("id", "main-iframe2");
theIframe2.setAttribute("src", "http://www.google.co.uk");
theIframe2.style.width = "300px";
theIframe2.style.height = "200px";
theIframe2.style.position = "absolute";
theIframe2.style.top = "0px";
theIframe2.frameBorder = 1;
var containerDiv2 = document.getElementById('container');
containerDiv2.appendChild(theIframe2);
It's also on jsfiddle here: http://jsfiddle.net/JxhFE/1/
Any advice would be appreciated.
Thanks,
Colin.
You can't show google.co.uk in an IFrame in your domain. Due to security reasons Google only allows it's homepage to be embedded from the same origin. (X-Frame-Options SAMEORIGIN header.)

Cannot change iFrame content in Firefox 4/IE

I have the following code:
<html>
<head>
</head>
<body>
<script type="text/javascript">
var frame = document.createElement('iframe');
frame.id = 'myFrame';
document.getElementsByTagName('body')[0].appendChild(frame);
var context = frame.contentWindow.document;
context.body.innerHTML = 'testing';
</script>
</body>
</html>
This creates a simple iframe containing my text: 'testing'.
This works perfectly in Chrome, but Firefox and IE are rendering an empty iframe.
Any idea what I'm doing wrong?
You can do something like this:
var frame = document.createElement('iframe');
frame.id = 'myFrame';
document.getElementsByTagName('body')[0].appendChild(frame);
frame = (frame.contentWindow) ? frame.contentWindow : (frame.contentDocument.document) ? frame.contentDocument.document : frame.contentDocument;
frame.document.open();
frame.document.write('testing');
frame.document.close();
Javascript is interpreted differently by all browsers, so it's just a matter of using the common-approach. This should work across all browsers.
Give it a try.
Some browsers explicitly prevent things like this so you can't, e.g., load somebody's bank website in a frame and interact with it in Javascript. This link:
http://spyder.wordpress.com/2006/05/31/hacking-around-firefox-security-in-order-to-actually-accomplish-something/
suggests that there are some bugs with how an empty iframe is initialized, and this one:
http://www.iframehtml.com/iframe-security.html
has some resources for how to deal with them.
Rewrote the last line innerHTML seems like a chrome only thing.
<script type="text/javascript">
var frame = document.createElement('iframe');
frame.id = 'myFrame';
document.getElementsByTagName('body')[0].appendChild(frame);
var context = frame.contentWindow.document;
context.write('testing');
</script>
JS fiddle here confirms it's working in IE, Chrome and Firefox:
http://jsfiddle.net/thebeebs/mDMaj/

Categories