日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于UIWebView与js交互的问题

發(fā)布時間:2025/6/17 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于UIWebView与js交互的问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這個問題,在網(wǎng)上能看到不少,主要通過調(diào)用UIWebView的一個方法stringByEvaluatingJavaScriptFromString

來實(shí)現(xiàn),與js的交互問題,我想可能用的過程中會出現(xiàn)不少問題,所以,先開個文章來存放,等過2天用的時候?qū)憘€問題,總結(jié)下遇到的問題或者經(jīng)驗(yàn)什么的。

http://www.cnblogs.com/zhwl/archive/2013/04/19/3030244.html

這個網(wǎng)址里的內(nèi)容不錯,不少使用上面所說的那個方法,而且不只是單單的用oc調(diào)用js,還有用js調(diào)用oc!

在寫 JavaScript 的時候,可以使用一個叫做 window 的對象,像是我們想要從現(xiàn)在的網(wǎng)頁跳到另外一個網(wǎng)頁的時候,就會去修改 window.location.href 的位置;在我們的 Oective C 程序碼中,如果我們可以取得指定的 WebView 的指標(biāo),也就可以拿到這個出現(xiàn)在 JavaScript 中的 window 對象,也就是 [webView windowScriptOect]。

這個對象就是 WebView 里頭的 JS 與我們的 O C 程序之間的橋樑-window 對象可以取得網(wǎng)頁里頭所有的 JS 函數(shù)與對象,而如果我們把一個 O C 對象設(shè)定成 windowScriptOect 的 value,JS 也便可以調(diào)用 O C 對象的 method。于是,我們可以在 O C 程序里頭要求 WebView 執(zhí)行一段 JS,也可以反過來讓 JS 調(diào)用一段用 O C 實(shí)作的功能。

※ 用 Oective C 取得與設(shè)定 JavaScript 對象

要從 O C 取得網(wǎng)頁中的 JavaScript 對象,也就是對 windowScriptOect 做一些 KVC 調(diào)用,像是 valueForKey: 與 valueForKeyPath:。如果我們在 JS 里頭,想要知道目前的網(wǎng)頁位置,會這麼寫:

varlocation = window.location.href;

用 OC 就可以這麼調(diào)用:

NSString*location = [[webView windowScriptOect] valueForKeyPath:@"location.href"];

如果我們要設(shè)定 window.location.href,要求開啟另外一個網(wǎng)頁,在 JS 里頭:

window.location.href ='http://spring-studio.net';

O C:

[[webView windowScriptOect] setValue:@"http://spring-studio.net"forKeyPath:@"location.href"];

由于 O C 與 JS 本身的語言特性不同,在兩種語言之間相互傳遞東西之間,就可以看到兩者的差別-

?

  • JS 雖然是 OO,但是并沒有 class,所以將 JS 對象傳到 O C 程序里頭,除了基本字串會轉(zhuǎn)換成 NSString、基本數(shù)字會轉(zhuǎn)成 NSNumber,像是 Array 等其他對象,在 O C 中,都是 WebScriptOect 這個 Class。意思就是,JS 的 Array 不會幫你轉(zhuǎn)換成 NSArray。
  • 從 JS 里頭傳一個空對象給 O C 程序,用的不是 O C 里頭原本表示「沒有東西」的方式,像是 NULL、nil、NSNull 等,而是專屬 WebKit 使用的 WebUndefined。?

所以,如果我們想要看一個 JS Array 里頭有什麼東西,就要先取得這個對象里頭叫做 length 的 value,然后用 webScriptValueAtIndex: 去看在該 index 位置的內(nèi)容。假如我們在 JS 里頭這樣寫:

varJSArray = {'zonble','dot','net'}; for(vari = 0; i < JSArray.length; i++) {console.log(JSArray[i]); }

O C 里頭就會變成這樣:

WebScriptOect *O = (WebScriptOect *)JSArray; NSUIntegercount = [[O valueForKey:@"length"] integerValue]; NSMutableArray*a = [NSMutableArrayarray]; for(NSUIntegeri = 0; i < count; i++) {NSString*item = [O webScriptValueAtIndex:i];NSLog(@"item:%@", item); }

?※ 用 Oective C 調(diào)用 JavaScript function

?

要用 O C 調(diào)用網(wǎng)頁中的 JS function,大概有幾種方法。第一種是直接寫一段跟你在網(wǎng)頁中會撰寫的 JS 一模一樣的程序,叫 windowScriptOect 用 evaluateWebScript: 執(zhí)行。例如,我們想要在網(wǎng)頁中產(chǎn)生一個新的 JS function,內(nèi)容是:

?

functionx(x) {returnx + 1; }

所以在 O C 中可以這樣寫;

[[webView windowScriptOect] evaluateWebScript:@"function x(x) { return x + 1;}"];

接下來我們就可以調(diào)用 window.x():?

NSNumber*result = [[webView windowScriptOect] evaluateWebScript:@"x(1)"]; NSLog(@"result:%d", [result integerValue]);// Returns 2

由于在 JS 中,每個 funciton 其實(shí)都是對象,所以我們還可以直接取得 window.x 叫這個對象執(zhí)行自己。在 JS 里頭如果這樣寫:

window.x.call(window.x, 1);

O C 中便是這樣:

WebScriptOect *x = [[webView windowScriptOect] valueForKey:@"x"]; NSNumber*result = [x callWebScriptMethod:@"call"withArguments:[NSArrayarrayWithOects:x, [NSNumbernumberWithInt:1],nil]];

這種讓某個 WebScriptOect 自己執(zhí)行自己的寫法,其實(shí)比較不會用于從 O C 調(diào)用 JS 這一端,而是接下來會提到的,由 JS 調(diào)用 O C,因?yàn)檫@樣 JS 就可以把一個 callback function 送到 O C 程序里頭。

如果我們在做網(wǎng)頁,我們只想要更新網(wǎng)頁中的一個區(qū)塊,就會利用 AJAX 的技巧,只對這個區(qū)塊需要的資料,對 server 發(fā)出 request,并且在 request 完成的時候,要求執(zhí)行一段 callback function,更新這一個區(qū)塊的顯示內(nèi)容。從 JS 調(diào)用 O C也可以做類似的事情,如果 O C 程序里頭需要一定時間的運(yùn)算,或是我們可能是在 O C 里頭抓取網(wǎng)路資料,我們便可以把一個 callback function 送到 O C 程序裡,要求 O C 程序在做完工作后,執(zhí)行這段 callback function。

※ DOM

WebKit 里頭,所有的 DOM 對象都繼承自 DOMObject,DOMObject 又繼承自 WebScriptObject,所以我們在取得了某個 DOM 對象之后,也可以從 Obj C 程序中,要求這個 DOM 對象執(zhí)行 JS 程序。

假如我們的網(wǎng)頁中,有一個 id 叫做 “#s” 的文字輸入框(text input),而我們希望現(xiàn)在鍵盤輸入的焦點(diǎn)放在這個輸入框上,在 JS 里頭會這樣寫:

document.querySelector('#s').focus();

Obj C:

DOMDocument *document = [[webView mainFrame] DOMDocument]; [[document querySelector:@"#s"] callWebScriptMethod:@"focus"withArguments:nil];

?

※ 用 JavaScript 存取 Objective C 的 Value

?

要讓網(wǎng)頁中的 JS 程序可以調(diào)用 Obj C 對象,方法是把某個 Obj C 對象注冊成 JS 中 window 對象的屬性。之后,JS 便也可以調(diào)用這個對象的 method,也可以取得這個對象的各種 Value,只要是 KVC 可以取得的 Value,像是 NSString、NSNumber、NSDate、NSArray、NSDictionary、NSValue…等。JS 傳 Array 到 ObjC 時,還需要特別做些處理才能變成 NSArray,從 Obj C 傳一個 NSArray 到 JS 時,會自動變成 JS Array。

?

首先我們要注意的是將 Obj C 對象注冊給 window 對象的時機(jī),由于每次重新載入網(wǎng)頁,window 對象的內(nèi)容都會有所變動-畢竟每個網(wǎng)頁都會有不同的 JS 程序,所以,我們需要在適當(dāng)?shù)臅r機(jī)做這件事情。我們首先要指定 WebView 的 frame loading delegate(用 setFrameLoadDelegate:),并且實(shí)作 webView:didClearWindowObject:forFrame:,WebView 只要更新了 windowScriptObject,就會調(diào)用這一段程序。假如我們現(xiàn)在要讓網(wǎng)頁中的 JS 可以使用目前的 controller 對象,會這樣寫:

?

- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowObject forFrame:(WebFrame *)frame {[windowObject setValue:selfforKey:@"controller"]; }

?

如此一來,只要調(diào)用 window.controller,就可以調(diào)用我們的 Obj C 對象。假如我們的 Obj C Class 里頭有這些成員變數(shù):

?

@interfaceMyController :NSObject {IBOutletWebView *webView;IBOUtlet NSWindow*window;NSString*stringValue;NSIntegernumberValue;NSArray*arrayValue;NSDate*dateValue;NSDictionary*dictValue;NSRectframeValue; } @end

?

指定一下 Value:

?

stringValue =@"string"; numberValue = 24; arrayValue = [[NSArrayarrayWithObjects:@"text", [NSNumbernumberWithInt:30],nil] retain]; dateValue = [[NSDatedate] retain]; dictValue = [[NSDictionarydictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2",@"value3",@"key3",nil] retain]; frameValue = [window frame];

?

用 JS 讀讀看:

?

varc = window.controller; varmain = document.getElementById('main'); varHTML =''; if(c) {HTML +='<p>'+ c.stringValue +'<p>';HTML +='<p>'+ c.numberValue +'<p>';HTML +='<p>'+ c.arrayValue +'<p>';HTML +='<p>'+ c.dateValue +'<p>';HTML +='<p>'+ c.dictValue +'<p>';HTML +='<p>'+ c.frameValue +'<p>';main.innerHTML = HTML; }

?

結(jié)果如下:

?

string24text,302010-09-09 00:01:04 +0800{ key1 = value1; key2 = value2; key3 = value3; }NSRect: {{275, 72}, {570, 657}}

?

不過,如果你看完上面的范例,就直接照做,應(yīng)該不會直接成功出現(xiàn)正確的結(jié)果,而是會拿到一堆 undefined,原因是,Obj C 對象的 Value 預(yù)設(shè)被保護(hù)起來,不會讓 JS 直接存取。要讓 JS 可以存取 Obj C 對象的 Value,需要實(shí)作 +isKeyExcludedFromWebScript: 針對傳入的 Key 一一處理,如果我們希望 JS 可以存取這個 key,就回傳 NO:

?

+ (BOOL)isKeyExcludedFromWebScript:(constchar*)name {if(!strcmp(name,"stringValue")) {returnNO;}returnYES; }

?

除了可以讀取 Obj C 對象的 Value 外,也可以設(shè)定 Value,相當(dāng)于在 Obj C 中使用 setValue:forKey:,如果在上面的 JS 程序中,我們想要修改 stringValue,直接調(diào)用 c.stringValue = ‘new value’ 即可。像前面提到,在這裡傳給 Obj C 的 JS 對象,除了字串與數(shù)字外,class 都是 WebScriptObject,空對象是 WebUndefined。

?

※ 用 JavaScript 調(diào)用 Objective C method

?

Obj C 的語法沿襲自 SmallTalk,Obj C 的 selector,與 JS 的 function 語法有相當(dāng)?shù)牟町悺ebKit 預(yù)設(shè)的實(shí)作是,如果我們要在 JS 調(diào)用 Obj C selector,就是把所有的參數(shù)往后面擺,并且把所有的冒號改成底線,而原來 selector 如果有底線的話,又要另外處理。假使我們的 controller 對象有個 method,在 Obj C 中寫成這樣:

?

- (void)setA:(id)a b:(id)b c:(id)c;

?

在 JS 中就這麼調(diào)用:

controller.setA_b_c_('a','b','c');

實(shí)在有點(diǎn)丑。所以 WebKit 提供一個方法,可以讓我們把某個 Obj C selector 變成好看一點(diǎn)的 JS function。我們要實(shí)作 webScriptNameForSelector:

?

+ (NSString*)webScriptNameForSelector:(SEL)selector {if(selector ==@selector(setA:b:c:)) {return@"setABC";}returnnil; }

?

以后就可以這麼調(diào)用:

?

controller.setABC('a','b','c');

?

我們同樣可以決定哪些 selector 可以給 JS 使用,哪些要保護(hù)起來,方法是實(shí)作 isSelectorExcludedFromWebScript:。而我們可以改變某個 Obj C selector 在 JS 中的名稱,我們也可以改變某個 value 的 key,方法是實(shí)作 webScriptNameForKey:。

?

有幾件事情需要注意一下:

?

用 JavaScript 調(diào)用 Objective C 2.0 的 property

?

在上面,我們用 JS 調(diào)用 window.controller.stringValue,與設(shè)定里頭的 value 時,這邊很像我們使用 Obj C 2.0 的語法,但其實(shí)做的是不一樣的事情。用 JS 調(diào)用 controller.stringValue,對應(yīng)到的 Obj C 語法是 [controller valueForKey:@"stringValue"],而不是調(diào)用 Obj C 對象的 property。

?

如果我們的 Obj C 對象有個 property 叫做 stringValue,我們知道,Obj C property 其實(shí)會在編譯時,變成 getter/setter method,在 JS 里頭,我們便應(yīng)該要調(diào)用 controller.stringValue() 與 controller.setStringValue_()。

?

?

?

?

后面的一些就不轉(zhuǎn)貼了,有興趣的去連接里面查看。沒有機(jī)器暫時無法知道調(diào)試結(jié)果。

?

—————————————————————————————————————————————————————————————————————————————————

UIWebView?接管js調(diào)用的alert

?http://blog.sina.com.cn/s/blog_6796844601010nxj.html

js oc 互調(diào)

http://hi.baidu.com/sadusaga/item/9fabbabb28e826e94fc7fded\

Objective-C與js相互調(diào)用及傳參數(shù)注意

http://www.linuxidc.com/Linux/2013-06/85736.htm

轉(zhuǎn)載于:https://www.cnblogs.com/lingzhiguiji/p/3578253.html

總結(jié)

以上是生活随笔為你收集整理的关于UIWebView与js交互的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。