2012-09-15 7 views
12

JavaScriptをWebView(Cocoa)に注入するさまざまな方法を探しています。Objective-Cを使用したJavaScript注入方法

WebViewに読み込まれたHTMLファイルの<head>タグにJavaScriptを挿入しようとしています。

次の方法は私にとっては機能しません。それだけで(私がテストしたものから)なしネストされた括弧で、非常に簡単なJavaScriptで動作するようです:

[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"var script = document.createElement('script');" 
                "script.type = 'text/javascript';" 
                "script.text = \"some simple JavaScript" 
                "}\";" 
                "document.getElementsByTagName('head')[0].appendChild(script);"]]; 

はより複雑には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(); 
     }); 
    }); 
} 

答えて

8

<script>タグを追加するために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) ; 
} 

更新明示的な例:

あなたはテンプレートとして私の上記の例を使用する必要があります!

とにかく、処理には2つの部分があります.Javascript部分とObjective-C部分です。 Javascriptのレベルでは、これをやっている:

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

// call the function in the variable "someFunction": 
someFunction(); 

あなたが将来的に機能を参照することを気にしない場合、例えば、関数を変数に割り当てずにそれを行うにもすることができます。変数なしで無名関数を使用すると、次のようになります。

(function(){...})() ; 

代わりにあなたが最後に(<the function>)();

をやっているvar A = <the function>; A();行うのあなたが行うようなあなたの匿名関数は、引数を取る場合、パターンは次のようになります。

(function(var0, ..., varN){...})(arg0, ..., argN); 

あなたのコードのテンプレート、あなたのJSが終了するとことを使用して次のようになります。

これは、Webビューに実行させたいものです。これがWebviewに渡すコードです。しかし、あなたはObj-Cプログラムでその文字列を構築しなければなりません。現時点の引数(上記のコードでは123.456)を挿入するという "複雑さ"を伴います。

それは次のようになります。

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 ] ; 

は私が今十分に書いた:)

+0

あなたの上記の例では動作し、結果=考える「成功!」コンソールに印刷されます。しかし、 "success"の代わりに自分のjavascriptを使用すると、空白の引用符がコンソールに表示されます。何か案は? –

+0

関数を一度実行する場合は、コードを '(function(){...})()'に変更してください。 – nielsbot

+0

関数を複数回使用する場合は、2ステップを使用します。あなたの関数を変数に代入するには( 'submitFormForTime = function(time){...}')、関数を実行するたびに 'submitFormForTime(...)'を実行します。 – nielsbot

0

私はその後、私はコードを挿入し、ページをリロードしたい、ウェブビューからすべての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を設定することもできます。

0

私はこれを試しませんでしたが、問題が大かっことコードの複雑さにある場合は、バンドルに格納されたJSファイルを呼び出すことができます。多分それはそれを解決するでしょう。たとえば、

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

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

[webView stringByEvaluatingJavaScriptFromString:jsString]; 

エンコードの種類を設定すると、すべての角かっこを正しい方法で解析できます。

関連する問題