在本机iPhone应用程序中的UIWebView中使用InnerHTML是否存在错误?

时间:2011-01-03 16:04:22

标签: javascript iphone jquery uiwebview

我有一个相当大的HTML / JS / CSS应用程序,当在iPhone上使用Safari作为Web应用程序运行时效果很好。

在本机iPhone应用程序中的UIWebView中运行此相同的应用程序时,在jQuery中调用以无提示地创建HTML片段(即:$("<div>HELLO WORLD</div>");将不会创建元素。

我在干净的jQuery方法中跟踪了以下等效代码片段:

var div = document.createElement(“div”); div.innerHTML = “<div>HELLO WORLD</div>”;

当我看到div.outerHTML时,我明白了 <div>/<div>

div.innerHTML返回一个空字符串。

这似乎不是一个jQuery问题,也不会100%发生这种情况。我无法找到一个模式,但在某些情况下,它连续工作2-3次,有时如果连续失败5-6次。这似乎只出现在Objective-C应用程序中的UIWebView中运行应用程序时。另外我只在运行iOS 4.2的实际设备上看到这个,而不是模拟器。

有没有人碰到类似的东西?有人有修复吗?

3 个答案:

答案 0 :(得分:5)

我也有这个问题。它发生在手机的CPU非常繁忙时(比如说100%)。然后渲染引擎有时会忘记innerHTML设置。

我的unify project中包含的解决方案是测试childNodes中是否有元素,否则再次应用它。

var target = document.createElement("div");
var text = "<div>Hello World</div>";
target.innerHTML = text;
var self = this;
self.__intervalHandle = window.setInterval(function() {
  target.innerHTML = text:
  if (target.firstChild) {
    window.clearInterval(self.__intervalHandle);
    self.__intervalHandle = null;
  }
}, 100);

这会强制渲染引擎将innerHTML应用于DOM,并为渲染引擎提供一些时间(在此示例中为100 ms,在我们的测试中是一个很好的值)来处理它。

答案 1 :(得分:2)

嗯,Sebastian发布的解决方案[不是生产质量解决方案]有效,但我无法确认CPU负载是否会导致此问题。我在iOS主机上生成了大量后台负载,无法重现此问题。

经过进一步调查,渲染问题似乎是iOS shell取消导航的副作用。一旦导航被iOS shell取消,渲染引擎可能会将其视为不需要渲染更多UI [基本上不会在一小段时间内渲染任何东西]。

解决此问题的一种方法是将命令作为哈希(#)参数而不是URL发送到iOS shell。这样iOS shell就可以获取命令而不需要取消导航。这种方法似乎适用于下面的测试代码。因此,如果window.location设置为location1,则会发出“At:1”警告,而元素e2没有值。如果window.location设置为location2,则会提示“At:0”,元素e2具有值。

@Kevin,如果发生这种情况,你能否确认你取消了iOS主机上的导航。

测试代码:

<强>使用Javascript:

    var location1 = "myApp://Test";
    var location2 = "#myApp://Test";
    $("#change").live("click", function (e) {
        var element = document.getElementById("e1");
        window.location = location1; var i = 0;            
        element.innerHTML = "At: " + i;
        window.__intervalHandle = window.setInterval(function () {
            var html = element.innerHTML;
            if (html) {
                 alert(html);
                window.clearInterval(window.__intervalHandle);
                window.__intervalHandle = null;
            } else {
                element.innerHTML = "At: " + ++i;
            }
        }, 1);
        document.getElementById("e2").innerHTML = "Test";
    });

iOS伪代码:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL* u = [ request URL];

if( [[u scheme] compare:@"myapp" ] == NSOrderedSame) {
{ 
return NO; // don’t navigate
}
return YES; // navigate
}

答案 2 :(得分:2)

你应该看看http://blog.techno-barje.fr/post/2010/10/06/UIWebView-secrets-part3-How-to-properly-call-ObjectiveC-from-Javascript

事实证明,取消导航作为-webView:shouldStartLoadWithRequest:委托方法的一部分可能会导致innerHTML出现问题。我更新了我们的JS代码以使用该文章中推荐的方法,并且我还没有看到innerHTML问题在一段时间内出现。