I'm looking to call a flash method from a method in javascript and recieve a result:
Example:
Flash -
ExternalInterface.addCallback("getProgress", getProgress) // Javascript to flash
public function getProgress():void {
ExternalInterface.call("getProgress", progress); // Send progress back to javascript from flash
}
Javascript -
Object.prototype = {
...
getProgress : function() {
$("#movie").getProgress();
return progress;
}
...
}
Anyone have any idea how to hook all this up???
Are you trying to pass the value of progress from flash to javascript or javascript to flash? From the wording of the question it seems that you want to call a flash method from javascript and receive a return value. But then why are you calling ExternalInterface.call from flash's getProgress method and returning progress from the javascript method?
change the flash part to:
ExternalInterface.addCallback("getProgress", getProgress)
public function getProgress():void
{
return progress;
}
And call
alert(window["moviename"].getProgress()); //IE
alert(document["moviename"].getProgress()); //Firefox
Checkout ExternalInterface example in livedocs.
Related
I have my swf being loaded using swfobject. From within AS3 I make a call which calls FB.ui to show the pay window. To this point everything works fine.
Once the payment is complete, FB.ui calls the callback which is supposed to call back to AS3. I get a reference to the swf object but the actual method call fails with Object doesn't support property or method.
I've been reading every post about this but can't find anything to help. It seems to me that getElementById isn't returning the correct object.
This only happens in IE. Chrome and FireFox work fine.
var attributes = {};
attributes.id = "game";
attributes.name = "game";
attributes.align = "middle";
swfobject.embedSWF(
"game.swf", "flashContent",
"800", "600",
swfVersionStr, xiSwfUrlStr,
flashvars, params, attributes);
// JavaScript enabled so display the flashContent div in case it is not replaced with a swf object.
swfobject.createCSS("#flashContent", "display:block;text-align:left;");
.....
FB.ui(obj, function(data) {
if(!data) {
alert("There was an error processing your payment. Please try again!");
return;
}
// alert('called back order');
// IMPORTANT: You should pass the data object back to your server to validate
// the contents, before fulfilling the order.
var gameVar = document.getElementById("game");
//alert(gameVar);
//console.log(Object.prototype.toString.call(gameVar));
//alert(gameVar.purchaseCallback);
gameVar.purchaseCallback(data);
//console.log("Payment verification complete");
});
//handle errors here
//alert('some error');
return false;
}
What makes this weirder is if I add the following to the page, clicking the link works.
function test() {
var game = document.getElementById("game");
alert(game.purchaseCallback);
}
test
So it turns out the issue is with the visibility. Since FB.ui changes the visibility of the object while the FB.ui dialog is displayed and then changes it back when the dialog is disposed of, the flash app loses it's ExternalInteface.
To correct this I added:
<style>
#game {
visibility: visible !important;
}
</style>
One more thing I should add. In IE 8 this may not work correctly. I made the following change to the params of the swf and it seems to work with everything now.
params.wmode = "opaque";
I'm developing a firefox extension which requires me to intercept page loads by filtering out some HTTPRequests.
I did that using the instructions given here. Please note that my question draws from the content of this link.
I used the method given under the section of HTTPObservers. And it worked, I am indeed able to extract the respective urls of the Requests being sent out.
However, another thing which I really require is to get the target DOM Window where the contents pertaining to the HTTPRequest were about to be loaded. Is it possible using HTTPObservers?
In the link above, another way has been described using WebProgressListeners.
I tried that out as well. The onLocationChange() method only returns location changes in the url bar. Is it somehow possible to get the HTTPRequest urls using any of these progress listeners? Because if so, then if I understand correctly, aWebProgress.DOMWindow would give me the window I require.
Note: I am using gwt for the extension and the JSNI for the above mentioned part.
You can usually do that by using nsILoadContext interface (sadly barely documented) attached to the request or its load group. Here is how you would do that:
function getWindowForRequest(request)
{
if (request instanceof Components.interfaces.nsIRequest)
{
try
{
if (request.notificationCallbacks)
{
return request.notificationCallbacks
.getInterface(Components.interfaces.nsILoadContext)
.associatedWindow;
}
} catch(e) {}
try
{
if (request.loadGroup && request.loadGroup.notificationCallbacks)
{
return request.loadGroup.notificationCallbacks
.getInterface(Components.interfaces.nsILoadContext)
.associatedWindow;
}
} catch(e) {}
}
return null;
}
Note that this function is expected to return null occasionally - not every HTTP request is associated with a window.
I need to know what should be done to use JavaScript in a HTML sitting in UIWebView to notify Objective-C that something has happened?
To be more exact, I'm playing some JavaScript animation in HTML and I need to alert the Objective-C code that the animation has ended.
There seems to be no official method of doing this. However, the standard workaround involves reading and parsing incoming URL requests, basically rolling your own serialized messaging protocol. The message handling should be done in the webView:shouldStartLoadWithRequest:navigationType method of your view controller.
Note: there are several free libraries (PhoneGap, QuickConnect, JS-to-Cocoa Bridge) which wrap this functionality (plus do a whole lot more). To reinvent the wheel (or know why it's round, so to speak), read on.
From JavaScript, you will invoke the callback by attempting to navigate to a new URL:
// In JavaScript
window.location = 'myapp:myaction:param1:param2'; // etc...
In Objective-C, implement the UIWebViewDelegate protocol in your .h file:
// In your header file
#interface MyAppViewController : UIViewController <UIWebViewDelegate> {
...
}
#end
Next, implement the method in your .m file:
// In your implementation file
-(BOOL)webView:(UIWebView *)webView2
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
// Break apart request URL
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:#":"];
// Check for your protocol
if ([components count] > 1 &&
[(NSString *)[components objectAtIndex:0] isEqualToString:#"myapp"])
{
// Look for specific actions
if ([(NSString *)[components objectAtIndex:1] isEqualToString:#"myaction"])
{
// Your parameters can be found at
// [components objectAtIndex:n]
// where 'n' is the ordinal position of the colon-delimited parameter
}
// Return 'NO' to prevent navigation
return NO;
}
// Return 'YES', navigate to requested URL as normal
return YES;
}
Two important notes:
Context: navigating to myapp:whatever will (of course) fail under any other context. Keep this in mind if you're loading cross-platform pages.
Timing: if a second window.location = call is made before the first returns, it will get 'lost.' So, either lump your calls together, manually delay execution, or implement a queue which combines the above with JS queries into Objective-C objects.
Actually for timing in iOS (maybe not for OSX?), if a second window.location call is made before the previous window.location call executes, then the first window.location call gets lost. I think the window.location call executes asynchronisely with the JavaScript after it is called, and if another call is made it before it executes, it cancels the first.
For example, when capturing touch events, I have seen ontouchstart not get sent via window.location, if an ontouchmove event occurs to quickly afterwards (such as in a fast finger swipe). Thus your Objective-C doesn't get the ontouchstart event. This is more of a problem on the original iPad than the iPad2, I assume because of processing speed.
zourtney's answer is correct , but forgot to mention one thing .. needed to register delegate to webview by
- (void)viewDidLoad {
[super viewDidLoad]; --- instantiate _webview next .. then
_webview.delegate = self; //important .. needed to register webview to delegate
}
hope this helps .....
Swift Version
class ViewController: UIViewController,UIWebViewDelegate{
#IBOutlet weak var webviewInstance: UIWebView!
override func viewDidLoad() {
webviewInstance.delegate = self
super.viewDidLoad()
}
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let requestString: String = (request.URL?.absoluteString)!
var components: [AnyObject] = requestString.componentsSeparatedByString(":")
// Check for your protocol
if components.count > 1 && (String(components[0]) == "myapp") {
// Look for specific actions
if (String(components[1]) == "myaction") {
// Your parameters can be found at
// [components objectAtIndex:n]
}
return false
}
return true
}
}
I am using Ajax's EnablePageMethods way to call server side code using javascript. The problem is that in IE8 the page automatically refreshes after the ajax call has been completed i.e. the server side function has been executed successfully. I want the same to happen with Chrome and Firefox but it doesnt refresh the page once the server side function has been executed.
Any idea or suggestion how to achieve that?
I am using this way to call server side code from Javascript --
http://www.codeproject.com/KB/ajax/Ajax_Call_using_AjaxNet.aspx
this is the javascript function:
function editNode(note) {
PageMethods.deleteNote(note);
}
and this is the server side function:
[System.Web.Services.WebMethod]
public static void deleteNote(int noteId)
{
string test = noteId.ToString();
Note note = new Note(noteId);
note.IsDeleted = true;
note.update();
}
this is where i am calling the javascript event:
<a href='myPageName.aspx' onclick='javascript:editNode(1);return false;'>Delete</a>
Here is how I did it:
function editNode(note) {
PageMethods.deleteNote(note,OnSuccess,OnFailure);
}
function OnSuccess() {
if (!navigator.appName == 'Microsoft Internet Explorer')
{
window.location.href=window.location.href;
}
}
function OnFailure(error) {
}
I found this solution on this link:
http://www.codedigest.com/CodeDigest/80-Calling-a-Serverside-Method-from-JavaScript-in-ASP-Net-AJAX---PageMethods.aspx
I have this in AS3
var myName:String = "David";
var result:Number = ExternalInterface.call("methodInJS", myName);
trace("Result from JS call is: "+result);
And in javascript
function methodInJS(name) {
alert("Hello to " + name);
return 17;
}
This allows me to send to javascript. What is the method to do the opposite. I want to send to flash.
SOLUTION: Looks like the addCallback works.
Thanks
I think you need to create an asynchronous call handler in Flex and then call that from JavaScript. See the docs here http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_4.html