I've been recently trying to implement a flash application, which at some point needs to be embedded via html. It looks something like>
<embed src=".." quality=".." ... and at some point FlashVars="&firstparam&secondparam..."
What I am trying to do is implement a dropdown, which would when pressed change that FlashVars parameter so the app shows something different. I've tried with
document.getoElementByID().FlashVars="new parameters"
but it doesn't work (it works perfectly for highlited default parameters such as src, height, width...)
I've also tried to write whole embed part again with javascript snippet, but it also didn't work. How is this done in javascript? I'm a beginner in this field so any help is greatly appreciated.
Thanks.
To understand why your code didn't work, you should understand what's flashvars parameter and how it's working.
Adobe said about that here, for example :
The FlashVars parameter of the HTML <OBJECT> tag sends variables into the top level of a SWF file when it loads in a web browser. The <OBJECT> tag is used to add SWF files to HTML pages. The <EMBED> tag can also be used, but is older and now obsolete.
So here we can understand that those variables are loaded when the SWF is loaded and that's why even if you've changed the flashvars parameter, that will do nothing, absolutely nothing to that loaded SWF which should be loaded again to get them (variables) applied.
So to do that, take this simple example :
HTML :
<div id='swf_container'>
<embed id='swf_object' src='swf.swf' flashvars='id=1' />
</div>
JavaScript :
// change the flashvars attribute
var swf_object = document.getElementById('swf_object');
swf_object.setAttribute('flashvars', 'id=2');
var swf_container = document.getElementById('swf_container');
var inner_html = swf_container.innerHTML;
// reload the swf object
swf_container.innerHTML = '';
swf_container.innerHTML = inner_html;
This manner is, of course, working but maybe it's not a good idea to reload the SWF object everytime we need it to do something, and that's why we have ExternalInterface to communicate between the SWF and JavaScript.
So in the case where you've access to the ActionScript code to create that SWF, you can use ExternalInterface to call any function in your SWF when it's already loaded.
For that, take this example :
ActionScript :
if(ExternalInterface.available)
{
// registers an AS function to be called from JS
ExternalInterface.addCallback('from_JS_to_AS', from_JS);
}
function from_JS(id:int) : void
{
// use the id sent by JS
}
JavaScript :
var swf_object = document.getElementById('swf_object');
swf_object.from_JS_to_AS(1234);
... and don't forget to use swfobject to avoid some browsers compatibility and to be sure that you establish the communication between your ActionScript side and the JavaScript one ...
Hope that can help.
Just do this :
$('embed') // targets the embed tag in the DOM
.attr("attribute-name","attribute-value");
Here's an example : https://jsfiddle.net/DinoMyte/1a6mwb13/2/
Related
I have seen some widgets online that gives the user the possibility of including a short Javascript snippet in their own page, which when executed displays an Iframe, like in the following example.
<div id="fb-root"></div><script src="http://connect.facebook.net/en_US/all.js#appId=APP_ID&xfbml=1"></script><fb:facepile></fb:facepile>
How can I do this by myself - have a javascript on my server, that when called on a remote server, writes out an iframe or loads content into their page?
The traditional way (considered a bit messy; won't work with XHTML-as-XML host pages; if called after page load via async, will blow up the entire page):
document.write('<iframe src="http://www.example.com/myframe" width="100" height="100"></iframe>');
Alternatively with innerHTML to an element on the page with a predefined name:
document.getElementById('examplecomframe').innerHTML= '<iframe src="http://www.example.com/myframe" width="100" height="100"></iframe>';
Or with DOM to insert just before the current <script> (though again that can be unpredictable if deferred):
(function() {
var iframe= document.createElement('iframe');
iframe.src= 'http://www.example.com/myframe';
iframe.width=iframe.height= 100;
document.getElementById('examplecomframe').appendChild(iframe);
})();
Or to insert just before the current script:
var scripts= document.getElementsByTagName('script');
var script= scripts[scripts.length-1];
script.parentNode.insertBefore(iframe, script);
I wouldn't use jQuery for third-party script inclusion. You'd have to load the whole heavy framework into the enclosing page, just for the sake of a few lines of JS. This can cause clashes with other frameworks (or different versions of jQuery) being used by the host page, something very rude for a third-party script to do.
I think you may have how this is working a bit mixed up. The way it's working is this:
1. User requests page from your domain/server, page is served.
2. Client web browser on users machine interprets said page, if a script block includes a reference to a js file at some other location then said js file is fetched.
3. Javascript is processed by the clients browser.
So really all you need is a JS file (plain old ASCII) on the server and have it do some document.write() calls to add the code you want it to add, for example:
go to http://www.shaunhusain.com/TestIFrameViaJS
three files there involved
index.html
anotherpage.html
testIFrame.js
let me know if it doesn't work out or I took a wrong direction for what you're looking for?
Shaun
To generate a Tag with jQuery you can use $('<tagname />') and pass an object with parameters (for example src).
Afterwards you append this iframe to the Dom. Using html() you can set the html-content of a selected element (in this case a tag with id example) to your iframe.
$(function() {
var iframe = $('<iframe />', {
src: 'http://example.com',
width: 100,
height: 100
});
$('#example').html(iframe);
});
http://api.fatherstorm.com/test/4159620.php
using jQuery for this...
$(document).ready(function() {
$('#fb-root').append('<iframe/>');
$('#fb-root iframe')
.attr('id','my_iframe')
.attr('src','http://www.cnn.com')
.css('width','100%')
.css('height','100%')
.attr('frameborder','no');
});
I would like to update the flashvars value argument to view another video:
<param name='flashvars' value='movieId=1002' />
I found out that I can make it work in Firefox by updating the parameter with the extra step of readding the whole flash contents.
$("param[name=flashvars]").attr("value", "movieId=33");
$("embed").attr("flashvars", "movieId=33");
$(".root").append($("#video"));
But this does not work in IE8 as the browser won't refresh the flash contents. Any ideas on how to reload the flash contents without external dependencies like swfobject.js?
I'm curious about this too. I'm trying to send a new string via flashvars to a SWF that I have no opportunity to change, and just changing the flashvars with jQuery, without having to use externalinterface, is the best option.
// update flashvars
var fv = 'foobar=1';
$("object param[name='flashvars']").attr("value", fv);
$("embed").attr("flashvars", fv);
// create new object to hold it
var obj = $("object");
// remove existing Flash from DOM
$("object").remove();
// add new HTML to DOM
$("#mviewer").append(obj.html());
If you want to change the flash vars and reload the Flash, you should just remove the SWF from the DOM and embed it again with your new vars (using SWFObject or whatever other method suits your fancy!).
If you want to change the flash vars without reloading the Flash, you're out of luck: there's no officially-supported way. In this case, you should use ExternalInterface to call ActionScript methods that update your values from JavaScript.
Instead of using flashvars, you could use the ExternalInterface AS3 class to send the new value to Flash.
ExternalInterface allows for a two way communication between AS3 & Javascript
Actually, why not use swfobject.js ?
I did like this :
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="js/swfobject.js"></script>
<div id="qsound"></div>
<script type="text/javascript">
if(q.sound) {
swfobject.embedSWF("js/dewplayer/dewplayer.swf", "qsound", "60", "20", "9.0.0", false, {'mp3': 'sounds/'+q.sound}, {'wmode': 'transparent'});
$('#qsound').show();
} else {
$('#qsound').hide();
}
</script>
I am having in issue with IE passing a string back into an swf using the EternalInterface class in Flash CS4.
I have an swf with the following code:
var externalString:String = ExternalInterface.call("IncomingJS")
which is inside an event listener attached to an Event.ENTERFRAME and an if statement waiting for ExternalInterface.available.
The IncomingJS function looks like:
function IncomingJS() {
return stringFromHTML;
}
and sits on the HTML page with the swf.
I am able to successfully get the externalString variable and procceed with the rest of the AS3 script in Firefox, Safari and Chrome, but not in IE.
If I add in an alert (stringFromHTML) before the return statement in the Javascript, I get the value of the stringFromHTML spammed, which looks like Flash is firing the function at the right rate.
The embed code in HTML for the swf is a little simple:
<object width="750" height="200" id="controlledScale"><param name="movie" value="http://www.myURL.com/controlledScale.swf"><param name="allowScriptAccess" value="sameDomain" /><embed src="http://www.myURL.com/controlledScale.swf" width="750" height="200" allowScriptAccess="sameDomain"></embed></object>
Any help or advice would be greatly appreciated.
Thanks,
DavidB
Edit
I realise how poor the SWF embed code is.
Unfortunately, the HTML code is actually working within a 3rd party HTML generator, and one of it's limitations is that I can only have a single line (with unlimited length) of html at a time.
Are the other options (swfObject etc) able to run either with no line breaks in the code, or would I be asking for trouble with Javascript and the SWF to, instead of embedding the SWF directly, use something like an iFrame and refer to a 'proper' flash delpoyment html file?
Kind of at a point on this one where I'm not even sure where the problem is actually located. The swf's are find sending out to Javascript across all browsers, just not getting info back in IE only.
You must add an id to the object tag to work in IE.
<object width="750" id="myflash" height="200"><param name="movie" value="http://www.myURL.com/controlledScale.swf"><param name="allowScriptAccess" value="sameDomain" /><embed src="http://www.myURL.com/controlledScale.swf" width="750" height="200" allowScriptAccess="sameDomain"></embed></object>
I pretty sure there is a security "feature" in IE that stops JS being called too many times from Flash, to stop it crashing the browser.
Is there a reason why you have to call it every frame?
I'd suggest against this at all costs as it's putting a LOT of extra stress on the browser.
***** EDIT *****
If you want to call an ExternalInterface method from JS -> Flash in IE you have to reference the object slightly differently, like this:
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
Then once you're sure the string you want to pass is constructed correctly you can call it like this from the JS:
thisMovie( "theFlashElementID" ).giveMeMyStringAlready();
Then in your Flash you would have something like this:
if( ExternalInterface.available )
{
ExternalInterface.addCallback( "giveMeMyStringAlready", handleTheStringFromJS );
}
else
{
handleTheFactIDontHaveExternalInterfaceAvailable();
// the only reason this would be is if container that
// is embedding the swf isn't fully loaded by the browser
}
The standout line from the AS3 docs regarding ExternalInterface is this:
Note: When using the External API with
HTML, always check that the HTML has
finished loading before you attempt to
call any JavaScript methods.
This:
Unfortunately, the HTML code is
actually working within a 3rd party
HTML generator
is the problem.
The swf is sitting inside a <form> tag.
At the browser stage, there is a huge volume of really verbose code, and I missed the tags at the very beginning and end of the html code.
Thanks for the help. If I have learnt nothing else from the experience, it's to be full with the question and look well beyond the immediate problem, breaking each element down as fully as I can.
I need to background load some WAV files for an HTML page using AJAX. I use AJAX to get the details of the WAV files, then use the embed tag, and I can confirm that the files have loaded successfully because when I set autostart to true, the files play. However, I need the files to play only when the user clicks on a button (or an event is fired). The following is my code to preload these files:
function preloadMedia() {
for(var i = 0; i < testQuestions.length; i++) {
var soundEmbed = document.createElement("embed");
soundEmbed.setAttribute("src", "/media/sounds/" + testQuestions[i].mediaFile);
soundEmbed.setAttribute("hidden", true);
soundEmbed.setAttribute("id", testQuestions[i].id);
soundEmbed.setAttribute("autostart", false);
soundEmbed.setAttribute("width", 0);
soundEmbed.setAttribute("height", 0);
soundEmbed.setAttribute("enablejavascript", true);
document.body.appendChild((soundEmbed));
}
}
I use the following code to play the file (based on what sound file that user wants to play)
function soundPlay(which) {
var sounder = document.getElementById(which);
sounder.Play();
}
Something is wrong here, as none of the browsers I have tested on play the files using the code above. There are no errors, and the code just returns.
I would have left it at that (that is - I would have convinced the client to convert all WAV's to MP3 and use MooTools). But I realized that I could play the sound files, which were not dynamically embeded.
Thus, the same soundPlay function would work for a file embeded in the following manner:
<embed src="/media/sounds/hug_sw1.wav" id="sound2" width="0" heigh="0" autostart="false" enablejavascript="true"/>
anywhere within the HTML.
And it plays well in all the browsers.
Anyone have a clue on this? Is this some sort of undocumented security restriction in all the browsers? (Please remember that the files do get preloaded dynamically, as I can confirm by setting the autostart property to true - They all play).
Any help appreciated.
Hmm.. perhaps, you need to wait for the embed object to load its "src" after calling preloadMedia() ?
Are you sure that the media file is loaded when you call soundPlay() ?
i know your question got a bit old by now, but in case you still wonder...
soundEmbed.setAttribute("id", testQuestions[i].id);
you used the same id twice, yet getElementById returns only one element, or false if it doesn't find exactly one matching element.
you could try something like this:
soundEmbed.setAttribute("id", "soundEmbed_"+testQuestions[i].id);
always keep in mind that an id must be unique
Just a tip for more compatibility:
I read here that width and height need to be > 0 for Firefox on MacOS.
I'm attempting to call a javascript function (in our code) from a silverlight control. I'm attempting to call the function via:
HtmlPage.Window.Invoke("showPopup", new string[] { "http://www.example.com" });
and I get the error "Failed to Invoke: showPopup"
I can call HtmlPage.Window.Invoke("alert", new string[]{"test"}); without issue, but not my own function.
I can also open up the page in question in the IE developer tools and manually call showPopup("http://www.example.com") and it works as expected.
So the js function works, and the Silverlight binary can find other js functions. What am I missing here?
Additional Notes:
The function call is in a button click event handler, so it happens after the page (and the script) have been loaded)
Aha! I figured it out. Our app uses an iframe, so the rendered html looks something like this
<html>
<head></head>
<body>
Stuff
<iframe>
<html>
<head></head>
<body>Other Stuff</body>
</html>
</iframe>
<body>
</html>
And the Silverlight control in question is in the iframe. The problem was that the file that contained the showPopup function was referenced in the outer <head> (why I could call the function with the IE toolbar) but not the inner <head>. Adding a reference to the file in the in-the-iframe <head> solved the problem.
Sort of anticlimactic, but thanks for all the help.
Actually referencing the script again from the iframe is not the most efficient way to reference code contained in the parent. If your function is called "showPopup", you can insert this in your iframe:
<script type="text/javascript">
var showPopup = parent.showPopup;
</script>
And voilĂ . The explanation for this is that all "global" functions and objects are part of this "global namespace"... which is the "window" object. So if you're trying to access "global" functions from a child, you need to either call the function on the parent (e.g parent.showPopup('....')) or declare a local alias for it (which is what we do in the above example).
Cheers!
Is the showPopup javascript function on the same html or aspx page as the Silverlight control? You will normally get the "Failed to Invoke ..." error if the javascript function does not exist:
HtmlPage.Window.Invoke("functionThatDoesNotExist", new [] { "Testing" });
What browser are you using when you are getting this problem?
Are you using the latest version of Silverlight?
Are you using the ScriptableType attrbiute anywhere?
Is it possible to list the code for a short but complete program that causes this problem to happen on your machine...
Make sure your script is fully loaded before trying to invoke functions from it.
Here's how I do it. But I'm creating silverlight without visual studio. I just have raw html, xaml, and js (javascript). Notice MouseLeftButtonUp and it's value "LandOnSpace"
<Canvas x:Name="btnLandOnSpace" Background="LightGreen" MouseLeftButtonUp="LandOnSpace"
Cursor="Hand" Canvas.Top ="0" Width="70" Height="50">
<TextBlock Text="LandOnSpace" />
</Canvas>
function LandOnSpace(sender, e) { //on server
if (!ShipAnimateActive && !blnWaitingOnServer) {
blnWaitingOnServer = true;
RunServerFunction("/sqgame/getJSLLandOnSpace");
ShowWaitingBox();
};
else {
alert('Waiting on server.');
};
}
I had the same problem in VS 2010 with SL 4. I had created a few methods and put them into one single JS file. However this file had not been added to the head section of the ASPX file. Adding it solved the problem. The difference is that though I did not have a separate head section in the iframe, I had the problem and it got solved.