window.location经常被调用?

时间:2011-02-07 16:49:57

标签: javascript android

我正在尝试拦截window.location更改以在Android应用中执行一些本机工作。更具体地说,我在WebViewClient中覆盖了这个调用:

public boolean shouldOverrideUrlLoading(WebView view, String url) 

查找以“native://”开头的任何内容。 JavaScript代码是这样的。

function callNative() {
   window.location = "native://doSomeNativeWork()";
}

function callNativeManyTimes(count) {
   for(i = 0 ; i < count ; i ++) {
       callNative();
   }
}

<a href="javascript:callNativeManyTimes(40);" class="btn large">DoSomeNativeWork</a><br/>

我看到的问题是,如果我很快地调用“window.location = something”很多次(比如上面的代码中),我只会在本机代码端的WebViewClient中调用一次。如果我拨打电话50ms,我会得到所有人。我在想这个浏览器正在做一些优化。

我想我可以像这样解决这个问题:不要使用window.location,更改为将本机对象嵌入到javascript中,并在javascript中调用该对象上的方法。我只是想知道为什么会这样。有人可以更熟悉机智JS分享一些见解吗?

由于

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。你可以通过创建iframe来做到这一点。我使用原生网址创建iframe,然后在2秒后删除iframe,这样我们就不会在DOM上放置太多。对我来说就像一个魅力。您可以根据需要创建任意数量的iframe。

我还在iframe网址上加了一个缓存破坏程序,即使我不确定它是否需要。更好的安全然后抱歉。

function callNative(url){
    var _frame = document.createElement('iframe');
    _frame.width=0; _frame.height=0;_frame.frameBorder=0;
    document.body.appendChild(_frame);
    if (url.indexOf('?') >= 0){
        url = url + "&cb=";
    }else{
        url = url + "?cb=";
    }
    _frame.src = url + Math.round(Math.random()*1e16);
    // Remove the iframe
    setTimeout(function(){document.body.removeChild(_frame);}, 2000);
}

function callNativeManyTimes(count) {
   for(i = 0 ; i < count ; i ++) {
       callNative('native://doSomeNativeWork()');
   }
}

<a href="javascript:callNativeManyTimes(40);" class="btn large">DoSomeNativeWork</a><br/>

请注意,我在iOS上使用了上述方法。不确定它在Android上是否完全相同,但从判断问题和其他答案来看,我猜它是一样的。

答案 1 :(得分:1)

我猜测加载URL是异步的(在解析URL之前阻止脚本的执行可能是个坏主意)。因此,设置window.location可能只会排队加载新URL,这将在不同的线程中完成。

等待50毫秒是一个可能或可能不起作用的黑客。你需要找到一种不同的方法。您需要一些东西来保证每个URL都能得到解决。如果订单无关紧要,您可以像有人建议的那样使用图片。否则,您可以使用本机JavaScript接口(这可能是更好的方法)。