我正在开发一个Objective C应用程序,当用户滚动它时,它将大型HTML文档加载到UIWebView中。这是因为文档是20Mb,如果一次加载,往往会导致webview崩溃。我们的想法是将文档拆分为HTML块,并在用户滚动浏览时将新元素添加到文档中,并删除旧元素。
目前我正致力于将Objective C应用程序传递给文档中的javascript函数。我有以下Objective C代码:
- (BOOL)webView:(UIWebView *)webView2
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSString *url = [[request URL] absoluteString];
// Intercept custom location change, URL begins with "js-call:"
if ([url hasPrefix:@"js-call:"]) {
// Extract the selector name from the URL
NSArray *components = [url componentsSeparatedByString:@":"];
NSString *function = [components objectAtIndex:1];
// Call the given selector
[self performSelector:NSSelectorFromString(function)];
// Cancel the location change
return NO;
}
// Accept this location change
return YES;
}
- (void)loadNext {
int endIndex = [self.partIndexEnd intValue];
int newEndIndex = endIndex + 9;
if (newEndIndex >= [self.parts count] - 2){
newEndIndex = [self.parts count] - 2;
}
if (endIndex == newEndIndex){
return; // Already at the end of the document
}
int splitLen = 300;
NSRange range = NSMakeRange(endIndex, newEndIndex - endIndex);
for (NSString *html in [self.parts subarrayWithRange:range]) {
NSLog(@"%@", html);
NSString *htmlToSplit = html;
while ([htmlToSplit length] > 0) {
NSString *curHtml;
if ([htmlToSplit length] <= splitLen){
curHtml = htmlToSplit;
htmlToSplit = @"";
}
else {
curHtml = [htmlToSplit substringToIndex:splitLen + 1];
htmlToSplit = [htmlToSplit substringFromIndex:splitLen - 1];
}
NSString* result = [self.web stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"next('%@');", [curHtml gtm_stringByEscapingForAsciiHTML]]];
NSLog(@"START %@ END %@", curHtml, result);
}
}
[self.web stringByEvaluatingJavaScriptFromString:@"next(null);"];
NSLog(@"HTML = %@ *END*", [self.web stringByEvaluatingJavaScriptFromString:@"$('body').html();"]);
}
我在文档中有以下javascript:
var nextHtmlToAdd = '';
function next(html){
var retval = '';
try{
if (html){
if (html.match(/teststring/i)){
alert('teststring');
}
nextHtmlToAdd = nextHtmlToAdd + html;
retVal = 'appended';
alert(html);
} else {
// Finished sending HTML
alert('finished');
if (nextHtmlToAdd.match(/teststring/i)){
alert('encoded html contains teststring');
}
nextHtmlToAdd = $("<div/>").html(nextHtmlToAdd).text();
if (nextHtmlToAdd.match(/teststring/i)){
alert('html contains teststring');
}
alert(nextHtmlToAdd);
var elem = $(nextHtmlToAdd);
$('.endofsections').before(elem);
if (elem.text().match(/teststring/i)){
alert('element contains teststring');
}
if ($(document).text().match(/teststring/i)){
alert('document contains teststring');
}
nextHtmlToAdd = '';
retVal = 'finished';
}
} catch (err) {
alert('Error: ' + err.description);
retVal = 'error';
}
return retVal;
}
使用以下代码在jQuery的$(document).ready()事件中触发Objective C代码:
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "js-call:loadNext");
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
如果我单步执行代码,那么我看到的是运行的stringByEvaluatingJavaScriptFromString方法,并且返回'附加'作为结果或有时返回的指针无效。 Web视图中没有出现警报,并且html没有附加到nextHtmlToAdd,只有HTML的第一部分似乎正在正确传递给UIWebView。
我想知道的是,stringByEvaluatingJavaScriptFromString可以执行的javascript字符串的长度是否有限制,或者它可以执行的次数是多少?有没有其他方法可以做到这一点?
谢谢,
乔
答案 0 :(得分:4)
是的,stringByEvaluatingJavaScriptFromString
方法有限制。你需要知道的两个:
在前者中,你会产生异常,但在后者中它可能会“无声地”失败。您是否正在测试该方法的返回值?如果失败,它将返回nil
。由于上述原因之一,这可以是查看操作系统是否终止脚本的有用方法。