开发者

How to fix: "NPMethod called on non-NPObject wrapped JSObject" error?

HI,

I am trying to call a method defined in flash object from开发者_如何学编程 javascript (firefox-3.0/Linux) and getting the exception: "NPMethod called on non- NPObject wrapped JSObject".

If I use eval on window.document.flash_object.func() it throws "NPMethod called on non-NPObject wrapped JSObject".

Where as, if I define a javascript function in side the page as given below:

function myFunc() { return flash_object.func();

}

and later do a eval of window.document.myFunc() it works fine.

I am running the two evals through a test framework called Selenium. [eval(window.document.flash_object.func()) and eval(window.document.myFunc())].

The issues seems to be issue with invoking the flash-object method without passing 'this' reference. Here is sample html/js code to reproduce this issue: "NPMethod called on non-NPObject wrapped JSObject".

<script>
function changeColor() {
  mymovie.changeColor();
}
function getColorNP() {
 var func = mymovie.getColor;
 func();
}
</script>
<button type="button" onclick="getColorNP();">getColorNP</button>
<button type="button" onclick="getColor();">getColor</button>

getColorNP throws the exception
Error: NPMethod called on non-NPObject wrapped JSObject!
Source File: http://my.host/Colors/colors.html
getColorNP throws the exception
Error: NPMethod called on non-NPObject wrapped JSObject!
Source File: http://my.host/Colors/colors.html

Now, question to javascript gurus: Given flash object and a method name, how do I invoke the method on that object. Lets say, a function takes two arguments: a flash object, and a method name as string. I want to do an eval on object.method() inside that function. Is this possible, if so, can you please explain me how this can be done.

As flash object's method is not a standard javascript function, i think its not possible to function binding through bind(). Is there any other alternative?

Thx, Chandra


This error occures when you try set flash function(native code) to some variable and then call this variable. As an example take your functions:

function getColorNP() { // this will call error
 var func = mymovie.getColor;
 func();
}

function getColorNP() { //this will work
 mymovie.getColor();
}

Any way if you need to save your flash function to some variable you should wrap it with lambda function. Like so:

function getColorNP() { // this will work also
 var func = function(){mymovie.getColor()};
 func();
}

So when you use flash function in javascript you should not braking then links chain.


Did you take a look at Calling a Flex/AS3 Callback from Javascript

I am using selenium as well and there are these two projects to support flex/flash:

FlashSelenium: is an extension to the Selenium RC client driver that enables the Selenium RC client test drivers to call ActionScript methods of the Flex application. FlashSelenium relies in the developer to manually expose the Flex application specific methods and component. http://code.google.com/p/flash-selenium/

Selenium Flex API: is an extension to Selenium IDE and a mechanism that automatically exposes the Flex application UI components. http://code.google.com/p/sfapi/.

I recently start using them and got same issue you mentioned on (NPMethod called on non-NPObject wrapped JSObject!) when running test on firefox and it seems that firefox does not allow javaScript calling Flash when the JavaScript comes from another Window.

In my case, this issue was solved by calling selenium using *firefoxproxy.

Regards,


Wrapping the call into a closure is fine (and you don't need to eval)


function callFlash(domobj, method_name){
    domobj[method_name]()
}


A variation on this, I got the "NPMethod called on non-NPObject wrapped JSObject" error while trying to setup a jQuery window focus/blur event handler in Flash like so:

    if (ExternalInterface.available) {
      ExternalInterface.addCallback("on_focus", on_activate);
      ExternalInterface.addCallback("on_blur", on_deactivate);
      ExternalInterface.call("eval", "if ($) $(window).focus($('object')[0].on_focus);");
      ExternalInterface.call("eval", "if ($) $(window).blur($('object')[0].on_blur);");
    }

The fix was to defer the SWF selector by adding an extra function closure:

    if (ExternalInterface.available) {
      ExternalInterface.addCallback("on_focus", on_activate);
      ExternalInterface.addCallback("on_blur", on_deactivate);
      ExternalInterface.call("eval", "if ($) $(window).focus(function() { $('object')[0].on_focus() });");
      ExternalInterface.call("eval", "if ($) $(window).blur(function() { $('object')[0].on_blur() });");
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜