2012-09-15 31 views
12

Tôi đang tìm các phương pháp khác nhau để đưa JavaScript vào một WebView (trong Cocoa).Phương pháp tiêm JavaScript sử dụng Objective-C

Tôi đang cố gắng tiêm một số javascript vào thẻ <head> của tệp HTML đã được tải vào WebView.

Phương pháp sau đây không hiệu quả đối với tôi. Nó có vẻ chỉ làm việc với rất đơn giản JavaScript với không có dấu ngoặc lồng nhau (từ những gì tôi đã thử nghiệm):

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

Có cách nào khác để làm điều này với các chức năng Javascript/jQuery phức tạp hơn?

Mã đầy đủ Tôi cố gắng để tiêm là như sau:

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

Trả lời

8

Bạn không thể sử dụng jQuery để thêm <script> thẻ. Điều này đã được hỏi nhiều lần. Xem:

Bạn có thể làm điều đó với trình duyệt tích hợp chức năng, NHƯNG:

Nó sẽ làm việc để chỉ gán chức năng của bạn cho một biến trên trang của bạn và sau đó đánh giá nó? Một cái gì đó như:

-(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) ; 
} 

cập nhật ví dụ rõ ràng:

Bạn nên sử dụng ví dụ trên của tôi như là một mẫu!

Dù sao, có 2 phần cho quy trình ... Phần Javascript và phần Mục tiêu-C. Ở cấp độ Javascript, bạn đang làm điều này:

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

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

Bạn cũng có thể làm điều đó mà không gán chức năng cho một biến, ví dụ, nếu bạn không quan tâm đến đề cập đến chức năng trong tương lai. Làm điều đó mà không có biến và sử dụng chức năng ẩn danh trông giống như sau:

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

tức làthay vì làm var A = <the function>; A(); bạn đang làm (<the function>)();

Cuối cùng, nếu chức năng ẩn danh của bạn mất đối số, như của bạn không, mô hình trông như thế này:

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

Sử dụng đó như là một khuôn mẫu cho mã của bạn, JS của bạn kết thúc lên như:

(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); 

Vì vậy, đó là những gì bạn muốn xem web để thực hiện ... đó là mã chúng tôi vượt qua để webview. Nhưng bạn phải xây dựng chuỗi đó trong chương trình Obj-C của bạn, với "biến chứng" của việc chèn đối số thời gian hiện tại (123.456 trong mã ở trên).

Nó trông như thế này:

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

Tôi nghĩ rằng tôi đã viết đủ rồi :)

+0

ví dụ trên của bạn hoạt động, và kết quả = "thành công!" được in trong bảng điều khiển. Tuy nhiên, khi tôi sử dụng javascript của riêng tôi thay vì "thành công", dấu ngoặc kép trống được in trong bảng điều khiển. Bất kỳ ý tưởng? –

+0

Nếu bạn muốn chạy hàm của bạn một lần, hãy thay đổi mã thành '(hàm() {...})()' – nielsbot

+0

Nếu bạn định sử dụng hàm của mình nhiều lần, hãy sử dụng 2 bước. Gán hàm của bạn cho một biến ('submitFormForTime = function (time) {...}') sau đó mỗi lần bạn muốn thực hiện hàm của bạn làm 'submitFormForTime (...)'. – nielsbot

0

tôi sẽ nhận được tất cả các HTML từ xem web, sau đó tôi muốn tiêm mã và tải lại trang. Nó vẫn không phải là phương pháp tiêm đúng, nhưng nó có thể hoạt động.

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

Tất nhiên bạn có thể có URL cơ sở từ yêu cầu của bạn, nếu có thay thế số đó.

0

Tôi đã không thử điều này, nhưng nếu vấn đề là với các dấu ngoặc và sự phức tạp của mã, bạn có thể thử gọi một tệp JS được lưu trữ trong gói. Có lẽ nó giải quyết được điều đó. Ví dụ:

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

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

[webView stringByEvaluatingJavaScriptFromString:jsString]; 

Có thể đặt loại mã hóa giúp phân tích tất cả các dấu ngoặc vuông đúng cách.

Các vấn đề liên quan