9

UIWebViewユーザーがリンクをタップしたときに何かをする必要があります。タップを検出するために使用できるデリゲート コールバックがあります。

- (BOOL) webView: (UIWebView*) webView
    shouldStartLoadWithRequest: (NSURLRequest*) request
    navigationType: (UIWebViewNavigationType) navigationType
{
    if (navigationType == UIWebViewNavigationTypeLinkClicked) {
        …
    }
}

問題は、このコードがすべてのリンク クリックを処理しないことです。例として、プレーンな Google 検索結果ページは、リンクで奇妙なことをします:

<a href="http://example.com/" class="l" onmousedown="return rwt(…)">
    <em>Link Text</em>
</a>

この関数により、リンクがタップされたときrwtにイベントがトリガーされなくなります。UIWebViewNavigationTypeLinkClicked「他のページへの移動」バケットに分類されるすべてのイベントを確実に検出する方法はありますか?

4

4 に答える 4

6

これまでのところ、次の解決策に到達しました。まず、読み込まれたページに JS コードを挿入します。

function reportBackToObjectiveC(string)
{
    var iframe = document.createElement("iframe");
    iframe.setAttribute("src", "callback://" + string);
    document.documentElement.appendChild(iframe);
    iframe.parentNode.removeChild(iframe);
    iframe = null;
}

var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
    links[i].addEventListener("click", function() {
        reportBackToObjectiveC("link-clicked");
    }, true);
}

webView:shouldStartLoadWithRequest: navigationType:ユーザーがリンクをタップすると、デリゲート呼び出しのおかげで事前にわかります。

if ([[[request URL] scheme] isEqualToString:@"callback"]) {
    [self setNavigationLeavingCurrentPage:YES];
    return NO;
}

次に、別のリクエストが来て_navigationLeavingCurrentPagetrue の場合、ナビゲーション タイプ フラグが であっても、ユーザーがリンクをクリックしたことがわかりますUIWebViewNavigationTypeOther。いくつかの誤検知につながるのではないかと心配しているため、ソリューションを広範囲にテストする必要があります。

于 2013-01-18T10:51:13.120 に答える
1

イベントを監視するカスタム JavaScript を Web サイトの HTML コードに埋め込むことで、これを実行できると思います。監視するイベントに基づいて、カスタム URL スキームでページ リダイレクトをトリガーできます。 shouldStartLoadWithRequest でインターセプトします。

このようなもの:

<script>
// Function to capture events
function captureEvent(el) {
  window.location.href="callback://"+el.href;  
}

var elms = document.getElementsByTagName("a"); 
for (var i=0; i<elms.length; i++) {
  elms[i].addEventListener("onmousedown", function(){captureEvent(el)}, true); 

 }
</script>

次に、shouldStartLoadWithRequest で、callback:// url スキームを持つ NSURLRequest を検索し、必要なことを行うことができます。

これはテストされていませんが、このような方法で正しい方向に進む可能性があります。

また、これは言及されているので、はい、これを使用してカスタムスクリプトを任意の Web ページに追加できます。

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{
    [super webViewDidFinishLoad:webView];    
    [webView stringByEvaluatingJavaScriptFromString:@"document.body.insertAdjacentHTML('BeforeEnd','<script>....</script>');"];
}
于 2013-01-16T19:07:33.113 に答える
0

これを機能させるには、たくさんの問題がありました。UITapGestureRecognizer の使用は機能しますが、リンクの場合でも常にタップを受け取ります。残念ながら、リンクが認識されるまでに約 300 ミリ秒の遅延があります。これは、リンクが認識される前にジェスチャ認識エンジンがタップを取得することを意味し、タイミングの問題が発生します (万が一の場合に備えて待機時間をハードコードするべきではないため、さらに悪いことです)。 Appleはそれを変更します)。さらに、タップを 300 ミリ秒以上待つと、アプリのユーザー エクスペリエンスが低下します。

だから私がやったのは、リンク以外のタップを取得するすべての上に透明なdivをオーバーレイすることでした。次に、リンクをより高い Z レベルに配置します。最後に、すべてが を使用していることを確認してontouchend="javascript:window.location.href='...';"ください。ontouchend はタップ リリースでのみ動作します。これはユーザーが期待するものです。window.location.href を設定すると、新しいページが読み込まれ、すべてのタップが確実に呼び出さ-webView:shouldStartLoadWithRequest:navigationType:れ、URL をチェックして何をする必要があるかを確認できます。

HTML は次のようになります: ... ... ... ...

(「position: relative」が常に同じ位置に配置されるかどうかは完全にはわかりませんが、私の単純なページではうまく機能しました。マイレージは異なる場合があります。ただし、 z を取得するには position:something が必要です-動作するインデックス。)

于 2014-05-14T05:57:28.017 に答える