Sunday, November 20, 2011

在UIWebView执行Javascript

在UIWebView里执行Javascript

UIWebView可以当前页面为宿主环境执行js。
通过方法-(NSString*) stringByEvaluatingJavaScriptFromString:(NSString*)js
以字符串形式返回这个js的结果。

在代码里写大量js很麻烦。通过打包js文件到bundle,可以少很多问题。

@interface UIWebView (JS_EXT)

- (NSString*)loadEnhancementJs:(NSString*) jsName;

@end

@implementation UIWebView (JS_EXT)

// load js from bundle and execute it
- (NSString*)loadEnhancementJs:(NSString*) jsName {
    NSString* scriptName = jsName;
    NSString *path = [[NSBundle mainBundle] pathForResource:scriptName ofType:@"js"];
    NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    return [self stringByEvaluatingJavaScriptFromString:jsCode];
}

@end

添加js文件会产生一些问题。

  1. js文件会被当作可编译文件
  2. js文件不会被自动加入bundle
添加一个js文件后,进入build Phases。在Compilse Sources里去掉js文件。在Copy Bundle Resources里加入js文件。


执行Javascript时候会遇到的问题

  1. 执行时间超过10秒
  2. 受UIWebViewDelegate消息触发导致重复执行

避免执行时间超过10秒

  1. 先优化实现,避免执行时间超过10秒。
  2. 如果执行过程可以拆分成几个不相关的过程,那么分开调用stringByEvaluatingJavaScriptFromString方法。每次都可以获得10秒的执行时间。
  3. 如果是数据量巨大导致的。这时候可以设计一个保存执行上下文的数据。每次处理固定条数的数据。保存退出时候的上下文。通过timer延迟激活下一次执行。这可以完全依靠js实现。

把初始化标志存入document对象,避免重复执行

if( undefined == document.myfunc ) {
    document.myfunc = function() {
        // create function body
    }
    
    docState = document.readyState;
    if( "complete" != docState ) {
        document.addEventListener('DOMContentLoaded', document.myfunc, false);       
    } else {
        document.myfunc();
    }
}

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home