Я пытаюсь отобразить страницу HTML со встроенным кодом JavaScript внутри a System.Windows.Forms.WebBrowser
управление. Код JavaScript, как ожидают, будет взаимодействовать со средой встраивания через window.external
объект. Прежде, чем вызвать метод на window.external
, JavaScript, как предполагается, проверяет на существование метода. Если это не там, код должен вызвать универсальный метод нейтрализации.
// basic idea
if (typeof(window.external.MyMethod) != 'undefined') {
window.external.MyMethod(args);
} else {
window.external.Generic("MyMethod", args);
}
Однако проверяя на метод без аргументов с typeof
кажется уже, вызывает метод. Таким образом, если MyMethod
принимает любое положительное число аргументов, код выше будет работать отлично; но, если MyMethod
метод без аргументов, затем выражение typeof(window.external.MyMethod)
не проверит на его тип, но вызовет его, также.
Там какое-либо обходное решение к этому поведению? Я могу так или иначе выйти из выражения window.external.MyMethod
препятствовать тому, чтобы вызов метода произошел?
Я не отлаживал вашу точную ситуацию, но полагаю, что мои экстрасенсорные способности помогут разобраться, что здесь происходит.
Язык JScript делает различие между использованием функции и простым упоминанием о ней. Когда вы говорите
x = f;
это означает "присвоить переменной x ссылку на функцию, обозначенную f". Это упоминает f. Напротив,
x = f();
использует f. Это означает "вызвать функцию, обозначенную f, и присвоить возвращаемое значение x."
Короче говоря, функции в JScript - это по сути то, что мы считаем свойствами типа делегат в C#.
Некоторые языки не делают такого различия. В VBScript, если вы говорите x = f
и f - функция, это означает вызов функции, то же самое, что x = f()
. VBScript не делает синтаксически сильного различия между использованием и упоминанием функции.
Как все это реализовано, мы используем COM; в частности, мы используем OLE Automation. При диспетчеризации поля объекта для получения его значения движок JScript передает флаги, означающие либо "получение свойства", либо "вызов метода", в зависимости от того, было ли это использование или упоминание.
Но предположим, что ваш диспетчеризируемый объект был написан с расчетом на то, что он будет вызываться из VB. Возможно, он был написан на VB. Вполне разумно и законно для объекта VB сказать: "О, я вижу, вы спрашиваете меня о значении этого метода". Поскольку я не понимаю разницы между упоминанием метода и его использованием, я просто вызову его, независимо от того, какой флаг вы передадите".
Я не знаю, есть ли обходной путь, но я готов поспорить на доллар, что происходит то, что вызываемый объект предполагает, что вызывающий хочет семантику VB.
Попробуйте один из этих
/* 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")) {....
На самом деле я не уверен, поможет ли это, но попробуйте window.external ["MyMethod"]
.
Если это не помогает, попробуйте сохранить это значение в переменной и только потом проверьте тип этой переменной. Посмотрим, поможет ли это.