admin管理员组文章数量:1200781
I am trying to display an HTML page with embedded JavaScript code inside a System.Windows.Forms.WebBrowser
control. The JavaScript code is expected to interact with the embedding environment through the window.external
object. Before invoking a method on window.external
, JavaScript is supposed to check for the existance of the method. If it is not there, the code should invoke a generic fallback method.
// basic idea
if (typeof(window.external.MyMethod) != 'undefined') {
window.external.MyMethod(args);
} else {
window.external.Generic("MyMethod", args);
}
However, checking for a no-argument method with typeof
seems to invoke the method already. That is, if MyMethod
accepts any positive number of arguments, the code above will work perfectly; but, if MyMethod
is a no-argument method, then the expression typeof(window.external.MyMethod)
will not check for its type but invoke it, too.
Is there any work-around to this behavior? Can I somehow escape the expression window.external.MyMethod
to prevent the method call from occurring?
I am trying to display an HTML page with embedded JavaScript code inside a System.Windows.Forms.WebBrowser
control. The JavaScript code is expected to interact with the embedding environment through the window.external
object. Before invoking a method on window.external
, JavaScript is supposed to check for the existance of the method. If it is not there, the code should invoke a generic fallback method.
// basic idea
if (typeof(window.external.MyMethod) != 'undefined') {
window.external.MyMethod(args);
} else {
window.external.Generic("MyMethod", args);
}
However, checking for a no-argument method with typeof
seems to invoke the method already. That is, if MyMethod
accepts any positive number of arguments, the code above will work perfectly; but, if MyMethod
is a no-argument method, then the expression typeof(window.external.MyMethod)
will not check for its type but invoke it, too.
Is there any work-around to this behavior? Can I somehow escape the expression window.external.MyMethod
to prevent the method call from occurring?
6 Answers
Reset to default 9I have not debugged your exact situation but I believe my psychic powers can work out what is going on here.
The JScript language makes a distinction between use of a function and mere mention of it. When you say
x = f;
that says "assign a reference to the function identified by f to the variable x". It mentions f. By contrast,
x = f();
uses f. It means "call the function identified by f and assign the returned value to x."
In short, functions in JScript are essentially what we would think of as properties of delegate type in C#.
Some languages do not make this distinction. In VBScript, if you say x = f
and f is a function, that means to call the function, same as x = f()
. VBScript does not make a strong distinction syntactically between the use and mention of a function.
The way this is all implemented is we use COM; specifically, we use OLE Automation. When dispatching a field of an object to get its value, the JScript engine passes flags that mean either "property get" or "method invoke", depending on whether it was use or mention.
But suppose your object being dispatched was written with the expectation that it would be called from VB. Perhaps it was written in VB. It is perfectly reasonable and legal for a VB object to say "oh, I see you're asking me for the value of this method. Since I don't understand the difference between mentioning a method and using it, I'll just invoke it no matter which flag you pass".
I don't know if there is a workaround, but I'd be willing to bet as much as a dollar that what's happening is the invoked object is assuming that the caller wants VB semantics.
I found this
if ('MyMethod' in window.external)
does not invoke MyMethod
Try one of these
/* Methods for feature testing
* From http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
*/
function isHostMethod(object, property){
var t = typeof object[property];
return t == 'function' ||
(!!(t == 'object' && object[property])) ||
t == 'unknown';
}
function isHostObject(object, property){
return !!(typeof(object[property]) == 'object' && object[property]);
}
if (isHostObject(window.external, "MyMethod")) {....
This effect can be seen in desktop Internet Explorer. A script such as:
for (var i in window) {
console.log('window.' + i + ' = ' + window[i]);
}
will fail as soon as external
is reached.
It appears that window.external
is not a regular Javascript object, it is a VBScript object.
So statements such as window.external
and window['external']
are therefore VBScript statements -- and, as Eric L says, window.external
in VBScript is equivalent to window.external()
.
Mighty confusing. It appears also that this is the only object to behave in such a way on Internet Explorer.
For cross-browser mobile web apps which make use of IE Mobile's window.external.Notify()
to communicate with native on Windows Phone 8, but which would also want to set document.location
on iOS, testing for the existence of window.external.Notify
would seem logical -- but does not work for this reason.
I have not found a way of preventing this; it still happens when specifying type="text/javascript"
in the script
tag.
So really the only choice is workarounds: 1) Just do not use 0 parameter functions. 2) Make a checking function (taking a parameter) to detect if there is an external to call to.
if (typeof(window.external.HasExternal(null)) != 'undefined')
and check that instead of the function if the external functions are either all there or not there. 3) For each parameterless function you want, either make it use a bogus parameter or add a 1 parameter checking function for it if the external code varies in what functions it supports.
I'm actually not sure if it will help, but try window.external["MyMethod"]
.
If that doesn't help, try to store this value in a variable, and only then check type of that variable. See if that helps.
本文标签: cNoargument method on windowexternal is invoked when checking with typeofStack Overflow
版权声明:本文标题:c# - No-argument method on window.external is invoked when checking with typeof - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738619284a2103096.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
typeof window.external.MyMethod !== "undefined"
– Sean Kinsey Commented May 9, 2010 at 14:50window.external
on IE -- regular ways of testing for an object's existence on Javascript do not work forwindow.external
. – funkybro Commented Aug 13, 2013 at 7:17