使用Objective-C的JavaScript注入方法

使用Objective-C的JavaScript注入方法,javascript,iphone,objective-c,code-injection,Javascript,Iphone,Objective C,Code Injection,我正在寻找将JavaScript注入WebView的不同方法(在Cocoa中) 我试图将一些javascript注入到已加载到WebView的HTML文件的标记中 下面的方法对我不起作用。它似乎只适用于非常简单的JavaScript,没有嵌套括号(根据我的测试): 对于更复杂的JavaScript/jQuery函数,还有其他方法可以做到这一点吗 我尝试注入的完整代码如下所示: function submitFormForTime(time){ $(\".t_h\").each(funct

我正在寻找将JavaScript注入WebView的不同方法(在Cocoa中)

我试图将一些javascript注入到已加载到WebView的HTML文件的
标记中

下面的方法对我不起作用。它似乎只适用于非常简单的JavaScript,没有嵌套括号(根据我的测试):

对于更复杂的JavaScript/jQuery函数,还有其他方法可以做到这一点吗

我尝试注入的完整代码如下所示:

function submitFormForTime(time){
    $(\".t_h\").each(function(i, obj) {
        if ($(this).text() != time) return;
        $(this).parent().find(\"form\").each(function(i, obj){
            obj.submit();
        });
    });
}

我将从web视图获取所有HTML,然后注入代码并重新加载页面。这仍然不是一种合适的注射方法,但它可能有效

NSString *htmlDataString = [webView stringByEvaluatingJavaScriptFromString: @"document.documentElement.outerHTML"];
// use nsstring methds to find the place for injecting
// inject avascript code
[webView loadHTMLString:htmlDataString baseURL:nil];

当然,您的请求中可能有基本URL,如果有,请替换为nil。

我没有尝试过这样做,但是如果问题在于括号和代码的复杂性,您可以尝试调用存储在捆绑包中的JS文件。也许它能解决这个问题。例如:

NSData *fileData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@”submitFormForTime” ofType:@”js”]];

NSString *jsString = [[NSMutableString alloc] initWithData:fileData encoding:NSUTF8StringEncoding];

[webView stringByEvaluatingJavaScriptFromString:jsString];

也许设置编码类型有助于正确解析所有括号。

您不能使用jQuery添加
标记。这已经被问过很多次了。见:

您可以使用浏览器内置功能来完成此操作,但:

将函数分配给页面上的一个变量,然后对其求值是否有效?比如:

-(void)webViewDidFinishLoad:(UIWebView *)webView
{
    // add function to page:
    NSString * js = @"myFunction = function(){ return \"success!\"; }" ;
    [ webView stringByEvaluatingJavaScriptFromString:js ] ;

    // execute newly added function:
    NSString * result = [ webView stringByEvaluatingJavaScriptFromString:@"myFunction();"] ;
    NSLog(@"result=\"%@\"", result) ;
}
更新明确示例:

你应该使用我上面的例子作为模板

无论如何,这个过程有两个部分。。。Javascript部分和Objective-C部分。在Javascript级别,您正在执行以下操作:

// assign a function to the variable "someFunction":
var someFunction = function(){...};

// call the function in the variable "someFunction":
someFunction();
您也可以在不将函数指定给变量的情况下执行此操作,例如,如果您不关心将来引用函数的话。在不使用变量的情况下使用匿名函数的操作如下所示:

( function(){...} )() ;
( function(var0, ..., varN){...} )(arg0, ..., argN);
NSString * jsTemplate =
    @"( function(time) {"
    @"        $(\".t_h\").each(function(i, obj) {"
    @"            if ($(this).text() != time)  return;"
    @"            $(this).parent().find(\"form\").each(function(i, obj) {"
    @"                obj.submit();"
    @"            });"
    @"        });"
    @"    })( %g );" ;
NSString * js = [ NSString stringWithFormat:jsTemplate, 123.456 ] ;
NSString * result = [ webView stringByEvaluatingJavaScriptFromString:js ] ;
i、 e.不做
var A=;A()你正在做
()

最后,如果您的匿名函数像您的一样接受参数,则模式如下所示:

( function(){...} )() ;
( function(var0, ..., varN){...} )(arg0, ..., argN);
NSString * jsTemplate =
    @"( function(time) {"
    @"        $(\".t_h\").each(function(i, obj) {"
    @"            if ($(this).text() != time)  return;"
    @"            $(this).parent().find(\"form\").each(function(i, obj) {"
    @"                obj.submit();"
    @"            });"
    @"        });"
    @"    })( %g );" ;
NSString * js = [ NSString stringWithFormat:jsTemplate, 123.456 ] ;
NSString * result = [ webView stringByEvaluatingJavaScriptFromString:js ] ;
将其作为代码的模板,您的JS最终会是:

( function(time) {
    $(\".t_h\").each(function(i, obj) 
    {
        if ($(this).text() != time)  return;

        $(this).parent().find(\"form\").each(function(i, obj) {
            obj.submit();
        });
    });
})( 123.456 );
所以,这就是您希望web视图执行的内容。。。这就是我们传递给webview的代码。但是您必须在Obj-C程序中构建该字符串,插入当前时间参数(“代码>123.456”在上面的代码中)

看起来是这样的:

( function(){...} )() ;
( function(var0, ..., varN){...} )(arg0, ..., argN);
NSString * jsTemplate =
    @"( function(time) {"
    @"        $(\".t_h\").each(function(i, obj) {"
    @"            if ($(this).text() != time)  return;"
    @"            $(this).parent().find(\"form\").each(function(i, obj) {"
    @"                obj.submit();"
    @"            });"
    @"        });"
    @"    })( %g );" ;
NSString * js = [ NSString stringWithFormat:jsTemplate, 123.456 ] ;
NSString * result = [ webView stringByEvaluatingJavaScriptFromString:js ] ;

我想我已经写得够多了:)

上面的例子很有效,控制台中会打印result=“success!”。但是,当我使用自己的javascript而不是“success”时,控制台中会打印空白引号。有什么想法吗?如果您想只运行一次函数,请将代码更改为
(function(){…})(
如果要多次使用函数,请使用两个步骤。将函数分配给一个变量(
submitFormForTime=function(time){…}
),然后每次执行函数时都执行
submitFormForTime(…)
。必须修改代码才能执行上述操作之一。我的例子是基于两步版本Wait的,为了让函数只运行一次,你能帮我澄清一下吗?