使用Objective-C的JavaScript注入方法
我正在寻找将JavaScript注入WebView的不同方法(在Cocoa中) 我试图将一些javascript注入到已加载到WebView的HTML文件的使用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,没有嵌套括号(根据我的测试):
对于更复杂的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的,为了让函数只运行一次,你能帮我澄清一下吗?