AS3 - ExternalInterface.addCallback, Access of undefined property - javascript

I am trying to use javascript to run AS3 functions. When I attempt to compile I'm getting an "Access of undefined property" error message.
I've read a few things online about this but I'm still not understanding it. I want to have the flash file always listening for javascript.
Here is my AS3 code:
ExternalInterface.addCallback("song4", PauseMusicExt);
And my Javascript & HTML:
function returnVar3(song3) { return this[song3]; }
<input type="submit" name="playButton" id="playButton" value="Submit" onClick="returnVar('song3')"/>
Edit: Here is the pauseMusic function:
function pauseMusicExt():void
{
songPosition = channel.position;
channelSilence.stop();
channel.stop();
channel2.stop();
btnPlay.mouseEnabled = true;
}

I'm not sure about the extend of your app but you've got your addCallback function parameters mixed up..
See the doc, the first parameter is the name you want to expose the function as to javascript, the second is the actual internal AS3 function you want to trigger.
So the declaration should likely be something like:
ExternalInterface.addCallback("song4", pauseMusic);
(assuming that your function in the same scope as where you call addCallback)
That statement will create a "song4" method that you can call on your flash dom object
var fl = document.getElementById('myflashobject');
fl.song4()
After there's the issue that pauseMusic want a parameter (looks like you've made it a mouse event handler). You probably want to have a clean method that doesn't require a parameter like an internal as3 event param. Rewrite pauseMusic so it doesn't require it (you might need to create another method to handle the mouse event internally - like onPause(evt:MouseEvent), which then calls pauseMusic.
Edit: I don't know if a lot of people thought about doing that, but you can also totally use external interface to call firebug's console.log function to send messages to Firebug from flash (it's really helpful for debugging ExternalInterface issues, or any other flash problems - see the ExternalInterface.call function)

Hope u want to pause the audio player.
AS code :
ExternalInterface.addCallback("sndToAS",rcvdFmJS);
function rcvdFmJS(val){
if (val == "pause"){
audioPause();
}
}
JS code :
document.getElementById("movie").sndToAS("pause");

Related

Overriding core JS commands?

I'm trying to modify/limit/prevent access to certain JS commands of my browser. For example commands like navigator.clipboard; However, I'm not sure how to approach this.
Is it possible to override these commands with user-defined javascript injected in the page, or do i have to edit the browser's javascript compiler and re-compile it from source for this?
I'm not really familiar with browsers and want to save time by knowing a general direction to follow. Thanks
First of all navigator.clipboard is not a function, but here is an example using the read function of navigator.clipboard:
navigator.clipboard.read = function (originalFunction) {
return function (yourParamsYouWantForThisFunction) {
// Do Stuff you wanna do before the real call. For example:
console.log(yourParamsYouWantForThisFunction);
// Call the original function
return originalFunction.call();
};
}(navigator.clipboard.read); // Pass the original function reference as a parameter
You may wonder, why there are two function statements:
The first one is there, so that we can pass the original function at runtime. If we would not do that, we would not be able to access the original navigator.clipboard.read function.
The second function is the actual function, that you will be using later, when you call navigator.clipboard.read().

Basic JQuery syntax: What mechnaic is at work in this small (2 line) piece of JavaScript / JQuery

So here' s the piece of code. I'm very new to JavaScript so don't be afraid to explain the obvious
$(".my-css-class").on("click", function() {
($(this).attr("data-property-1"), $(this).attr("data-property-2"), this);
});
There's an element in the .jsp page that looks like this:
<i class="clickMe"></i>
I know the .jsp creates a link-icon, and that the above JavaScript is an event handler. I know that it passes these 3 values as arguments another JavaScript method:
function doStuff(prop1, prop2, obj) {
if (prop1 == 'foo') {
//do stuff with prop2
}
else{
// do stuff with obj
}
}
It all works fine. What I want to know is what exactly is going on to make it work? I can't find anything in the code that connects what the event-handler returns to the 'doStuff' java-script function.
The names are totally different, so it's not reflection, it can't be parameter matching because there's other functions with the same number and type of parameters in the file, it can't be convention based because it still works if I find/replace the name of the function to gibberish.
I guess basically I'm asking what this line is doing:
($(this).attr("data-property-1"), $(this).attr("data-property-2"), this);
tl;dr: I'm at a loss, I know how the properties get as far as the onClick event-handler's anonymous function - but how does JavaScript know to pass them as arguments the to the doStuff() function?
the onClick event is a standard event triggered on click of any clickable html element and is automatically raised by the DOM.
You are hooking in to this by listening on any matched ".my-css-class" elements for an onClick Event.
The jquery syntax ".on" has been simplified over time and allows you to hook into any number of events like "submit" - OnSubmit event , or "load" - onLoad Event
Wherever your on("click", myFunction) event hook is picked up, your myFunction will execute.
Looking at your second point...
because it still works if I find/replace the name of the function to gibberish.
The DoStuff function will be found and replaced across all files in your site? or page? or open tabs? , so therefore it must exist somewhere as "doStuff(" or "giberish(".
so when you do a global find/replace, do each one slowly, until you locate it.
Finally, when you do a view source in the browser, this should either explicitly show you the doStuff function, or at the very least give you a clue as to satelite files loaded at runtime, where you can go and investigate.
Use firebug in firefox to debug loaded resources; the ".net tab" to view external loaded resources and the html/javascript they might contain. (for example: your master page might be loading in an embeded resource that contains the doStuff method, becuase of a user or server control reference in that master page)
Also have a look at this:
http://www.developerfusion.com/article/139949/debugging-javascript-with-firebug/
You can step through the javascipt piece by peice until it hits the doStuff method.
Just remember to set at least 1 breakpoint ;-)

Cannot Call a Flash Function from Javascript

I've been all over here and can't find an answer. I have a .swf sitting in an HTML page and I am trying to call a function inside of it from javascript. I can talk out from flash to the javascript but I can't get it to talk back in. I know I am targeting the object properly because I use console.log() on it and confirms what it is targeting.
I'm triggering the test from flash, calling a javascript function from inside the .swf, and having that function call the internal Flash function.
Flash Code:
//adds callback
ExternalInterface.addCallback("sendToFlash", flashTalkedTo);
//function called by the callback
public function flashTalkedTo():void{
//runs another function in javascript to log a string
ExternalInterface.call("callMe")
}
//calls javascript that tries to talk to Flash
ExternalInterface.call("catchFromFlash")
Javascript Code:
//function called by Flash that initiates
function catchFromFlash(){
talkToFlash()
}
//function that tries to talk to flash
function talkToFlash(){
document.getElementById('Noodleverse').sendToFlash()
}
//function called by Flash in the end to confirm call made
function callMe(){
console.log("Call Me")
}
Any help works, thanks!
Flash, and plugins in general, are a little bit fiddly. They don't behave quite like normal elements, and their functions don't behave quite like normal functions. For example, you can't save the element into a value and call a function from that. You also need to be careful because in some browsers the object is used and in others the embed is used.
The best way to call a function is to use swfobject (https://code.google.com/p/swfobject/) to abstract everything. Personally though, I use this (based on experience, maybe somebody can offer improvements):
HTML:
<object id="myplugin" ...>
...
<embed name="myplugin" ... />
</object>
JavaScript:
var o1=document.myplugin;
if(o1&&!!o1.myFlashFunction){
return document.myplugin.myFlashFunction(); // DO NOT USE o1 here. It will fail.
}
var o2=window.myplugin;
if(o2&&!!o2.myFlashFunction){
return window.myplugin.myFlashFunction(); // DO NOT USE o2 here
}
The first case (document) is for most new browsers. For example, Chrome will find the embed object. The second (window) is for IE and finds the object (IE, at least old IE, ignores embed). I'm not 100% sure the second is needed, because IE might also work with document, so call that voodoo code. Also window.myplugin will give an array of all matching elements in Chrome, FireFox, etc. (but we expect those to already be taken care of)

Invoke JS method directly from CasperJS

I'm trying to test a page using CasperJS, in particular I want to poke the data model a bunch. Let's say I've got a basic function called taxes, and I want to ensure that it uses the right tax rate. So I'd like something like:
this.test.assert(taxes(100, 'Ontario') === 15, "Check ontario tax rate");
Rather than filling out a form and seeing what it prints. That taxes method exists in the global scope, so I'm able to execute it quite easily from anywhere (including from the console in firebug or Chrome). But it's not in the right scope for that to work inside CasperJS (I think? I'm getting ReferenceError: Can't find variable: taxes.
It seems like I'm missing something simple.
TL;DR: How do I execute an on-page bit of JS directly inside a CasperJS test?
Have you tried using evaluate()?
relevant quote: "execute code as if you were using the browser console."
something along the lines of:
casper.evaluate(function(amount, province) {
return taxes(amount, province);
}, {100, 'Ontario'});
Use assertEvalEquals() method.
If you're calling the method via a jQuery-style reference, make sure to explicitly include the library, lest you'll get the ReferenceError:
var casper = require('casper').create({
clientScripts: ['js/jquery-1.7.2.js']
});
...
casper.start('foo.php',
function() {
console.log(this.evaluate(function() {
return $('taxes').text();
}));
});
casper.run();
See: https://groups.google.com/forum/#!msg/casperjs/2uyUOqdzShw/bHWrJYXni40J
If you're calling it implicitly in the global scope (i.e., straight javascript, rather than, for example, $('taxes')), you might have to explicitly prepend the window or document namespace to the reference:
document.querySelector('#taxes').value = taxes_text;

Call AS3 MouseEvent function from JS

Is there any way to call MouseEvent function in as3 from JavaScript?
I have HTML button and swf object, I need to sent a POST request from swf by clicking on HTML button.
You can do this with the ExternalInterface api.
In your flash object, make a call like the following.
ExternalInterface.addCallback("someAPIMethod", anActionScriptMethod);
function anActionScriptMethod():void
{
// handle POST
}
Then in your JavaScript, You'll need to get the object of your embedded flash and call the "someAPIMethod" call back you have defined in your flash.
your markup may look something like...
<button id="someId" value="Click Me" onclick="onButtonClick();">Click Me</button>
Your JS may then look like...
function onButtonClick()
{
// get the flash object and call the callback method
flashObj(name).call("someAPIMethod");
}
// this probably won't work in all browsers, search the net for a better function.
function flashObj(name)
{
if (window.document[name])
{
return window.document[name];
}
return document.getElementById(name);
}
there will probably be tweaks that you need to make to this code but it should give you some direction to get started.

Categories