2009-08-02 10 views
11

Dans l'événement [webView: shouldStartLoadWithRequest: navigationType:], comment pouvez-vous faire la différence entre un iframe qui charge du contenu et le contenu de la page entière? Il semble que les deux appellent ce même événement avec les mêmes arguments, la seule différence étant l'URL qui va être chargée, donc il n'y a aucun moyen de faire la différence entre les deux.Comment faire la différence entre un chargement d'iframe et le chargement d'une page entière dans un UIWebView?

J'ai pensé à quelques façons de faire la différence cependant:

  • Parse le code source de la page et stocker une liste de tous les attributs iframe src, on suppose que si le chargement d'URL est un de ceux dans ma liste c'est un iframe. Bien sûr, cette hypothèse peut être incorrecte si elle navigue réellement vers la page.
  • Comme ci-dessus, mais exécutez du code JavaScript sur la page et pour obtenir les attributs src iframe.
  • L'utilisation de JavaScript, mis en place des crochets pour chaque fois qu'un utilisateur essaie de naviguer vers une page, semblable à http://niw.at/articles/2009/02/06/how-to-enable-the-popup-window-on-uiwebview/en
  • L'utilisation de JavaScript, mis en place des crochets juste avant un iframe tente de charger des données (ne sais pas comment je ferais quelque chose comme ça) .
  • Modifiez chaque attribut src d'iframe pour inclure une chaîne spéciale à la fin de son attribut src, par exemple. "# iframe-loading". Chargez le UIWebView avec ce code source modifié. Bien que cela ne fonctionne que pour les iframes qui existaient sur la page d'origine telle qu'elle a été interrogée la première fois, pas celles qui sont chargées dynamiquement, par ex. via JavaScript. Laissez la page se charger normalement en retournant YES dans l'événement [webView: shouldStartLoadWithRequest: navigationType:], et une fois le chargement terminé, vérifiez si l'URL de WebView a changé ou non ... si c'est le cas, il s'agit d'une redirection de page sinon, cela signifie probablement que c'était un iframe qui était chargé.
  • En utilisant JavaScript, remplacez le setter de propriété window.location pour exécuter mon propre code avant qu'il ne change réellement l'emplacement de la fenêtre. Je pourrais alors communiquer avec Objective-C pour lui faire savoir que la prochaine charge sera en fait une redirection. Est-ce la seule façon de rediriger en JavaScript?

Quelle est la meilleure façon de procéder? Pouvez-vous penser à des façons auxquelles je n'ai pas pensé? Les iframes ont-elles un événement/une propriété spéciale que je pourrais manipuler avec JavaScript pour m'aider?

Merci

Mise à jour: Ce n'est pas aussi simple que la vérification de la NavigationType. Bien que cliquer sur un lien pour ouvrir une nouvelle page apparaîtra comme navigationType = 0, une redirection JavaScript (changeant window.location) apparaîtra comme navigationType = 5. Une charge iframe apparaît aussi comme navigationType = 5. Alors quand navigationType = 5, vous ne savez pas si la page entière a changé les URL via JavaScript ou si c'est simplement un chargement iframe sur la même page.

+1

Tout comme un FYI, vous devriez éviter de se référer à Apple dénombrées types par leurs valeurs entières - par exemple navigationType == 5. Vous devriez plutôt, dans le code, vous y référer par leur nom, par ex. UIWebViewNavigationTypeOther. Est-ce que le compilateur réduit à un simple entier? Oui. Mais le faire de la bonne façon vous laisse isolé si elles changent l'ordre de leurs types énumérés, ou spécifiez un entier spécifique dans le futur. –

Répondre

6

Je viens d'utiliser cette méthode:

Laissez la charge page normalement en retournant OUI dans le [webView: shouldStartLoadWithRequest: NavigationType:] événement, et une fois qu'il a fait le chargement, voir si l'URL du WebView a changé ou non ... si cela signifiait que c'était une redirection de page, sinon cela signifiait probablement que c'était un iframe qui était chargé.

2

J'ai réussi à utiliser le champ HTTP "referer" (l'en-tête est mal orthographié) pour le détecter.Cela devrait soit être l'URL de la page principale (disponible à partir du webview) ou quelque chose d'autre - probablement un cadre.

NSString *referer = [request.allHTTPHeaderFields objectForKey:@"Referer"]; 
NSString *currentPage = [webView.request.mainDocumentURL absoluteString]; 
BOOL isFrameLoad = [referer isEqualToString:currentPage] == NO; 
+0

Cela ne fonctionne pas ces jours-ci. Aucun en-tête de référant. Je reçois: { Accepter = "text/html, application/xhtml + xml, application/xml; q = 0.9, */*; q = 0.8"; "User-Agent" = "Mozilla/5.0 (iPhone, CPU iPhone OS 6_1 comme Mac OS X) AppleWebKit/536,26 (KHTML, comme Gecko) Mobile/10B141"; } – philoye

35
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{ 

BOOL isFrame = ![[[request URL] absoluteString] isEqualToString:[[request mainDocumentURL] absoluteString]]; 

} 
+0

la seule réponse badass – Fattie

Questions connexes