【问题标题】:Triggering shouldStartLoadWithRequest with multiple window.location.href calls使用多个 window.location.href 调用触发 shouldStartLoadWithRequest
【发布时间】:2011-02-25 11:03:52
【问题描述】:

我试图通过 UIWebView 的 shouldStartLoadWithRequest 方法将 UIWebView 内的网页中的多个内容传递回我的 iPhone 应用程序。

基本上我的网页调用 window.location.href = "command://foo=bar" 并且我能够在我的应用程序中拦截它没问题。现在,如果我创建一个循环并一次执行多个 window.location.href 调用,那么 shouldStartLoadWithRequest 似乎只被调用一次,并且它获得的调用是在循环结束时最后一次触发 window.location.href 。

同样的事情发生在 Android 的 webview 上,只有最后一个 window.location.href 被处理。

【问题讨论】:

  • 我找到了一个聪明的解决方案。为每个命令动态创建一个 iframe 并将其 src 设置为“command://foo=bar”,您可以在一个循环中多次触发它,并且每次都会调用 shouldStartLoadWithRequest !现在研究如何优化这一点。我认为创建数千个 iframe(即使它们是隐藏的)并不好。对此有何建议?
  • 我也会尝试优化每个位置调用。如果您每分钟只能发送 60 个呼叫,那么请确保您使用足够的查询变量和片段来干扰每个呼叫,以便每次呼叫处理多个命令。此外,您可能想查看 wkWebView:nshipster.com/wkwebkit,它可以自动执行大部分过程并且更可靠。

标签: iphone uiwebview window.location


【解决方案1】:
iFrame = document.createElement("IFRAME");
iFrame.setAttribute("src", "command://foo=bar");
document.body.appendChild(iFrame); 
iFrame.parentNode.removeChild(iFrame);
iFrame = null;

所以这会创建一个 iframe,将它的源设置为我试图传递给应用程序的命令,然后一旦它附加到主体 shouldStartLoadWithRequest 被调用,然后我们从主体中删除 iframe,并将其设置为 null释放内存。

我还在 Android webview 上使用 shouldOverrideUrlLoading 对此进行了测试,它也能正常工作!

【讨论】:

  • 这个解决方案非常丑陋,但它似乎是最不丑陋的解决方案。似乎 Javascript 通过忽略随后被其他 window.location 调用替换的 window.location 调用来“优化”。感谢您将我从非常痛苦的调试过程中拯救出来!
  • @Arkaaito 为丑陋的人 +1,我完全同意
  • 我想跟进,因为我在 2 年前发布了这个。我编写了一个 Android 和 iPhone 应用程序,它基本上是一个封装在原生应用程序中的 webview。我使用了这个解决方案,因此我可以从 webview 与本机应用程序进行通信,并且在过去的 2 年中,我的应用程序下载量超过 50 万次。
  • 3 年跟进,4,000,000 次 ios+android 下载加起来,这个解决方案完美无缺。是的,它很丑,但它有效。
  • 你,先生,太棒了。我已经为此奋斗了好几个小时。最后,正确的谷歌搜索把我带到了这里。谢谢。
【解决方案2】:

我也遇到了这个问题,这是适合我的解决方案。 我所有的 JavaScript 函数都使用这个函数 __js2oc(msg) 来传递数据 以及通过 shouldStartLoadWithRequest 到 Objective-C 的事件: 附言将“command:”替换为您使用的“appname:”触发器。

/* iPhone JS2Objective-C bridge interface */
var __js2oc_wait = 300; // min delay between calls in milliseconds
var __prev_t = 0;
function __js2oc(m) {
  // It's a VERY NARROW Bridge so traffic must be throttled
  var __now = new Date();
  var __curr_t = __now.getTime();
  var __diff_t = __curr_t - __prev_t;
  if (__diff_t > __js2oc_wait) {
    __prev_t = __curr_t;
   window.location.href = "command:" + m;
  } else {
    __prev_t = __curr_t + __js2oc_wait - __diff_t;
    setTimeout( function() {
      window.location.href = "command:" + m;
    }, (__js2oc_wait - __diff_t));
  }
}

【讨论】:

    【解决方案3】:

    不,iframe 的 url 更改不会触发 shouldOverrideUrlLoading,至少在 Android 2.2 中不会。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 2020-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多