2009-08-02 16 views
11

W zdarzeniu [webView: shouldStartLoadWithRequest: nawigacjiType:], jak odróżnić element iframe, który ładuje treść, a całą zawartość ładującą stronę? Wygląda na to, że oba wywołują to samo zdarzenie z tymi samymi argumentami, a jedyną różnicą jest adres URL, który ma być załadowany, więc nie ma możliwości odróżnienia tych dwóch.Jak odróżnić ładowanie elementu iframe od ładowania całej strony w interfejsie UIWebView?

myślałem o kilku sposobów, aby odróżnić choć:

  • analizowania kodu źródłowego strony i przechowywać listę wszystkich atrybutów iframe src załóżmy, że jeśli ładowanie url jest jednym z tych na mojej liście to element iframe. Oczywiście to założenie może być niepoprawne, jeśli faktycznie przechodzi do strony.
  • To samo co powyżej, ale uruchom trochę kodu JavaScript na stronie i pobierz atrybuty src iframe.
  • Korzystanie JavaScript, założyć haki, gdy użytkownik próbuje przejdź do strony, podobne do http://niw.at/articles/2009/02/06/how-to-enable-the-popup-window-on-uiwebview/en
  • użyciu JavaScript, założyć haki tuż przed iframe próbuje ładowanie danych (nie wiem, jak ja bym zrobił coś takiego) .
  • Zmodyfikuj atrybut src każdego elementu iframe, aby zawierał specjalny ciąg na końcu atrybutu src, np. "# iframe-loading". Załaduj UIWebView z tym zmodyfikowanym kodem źródłowym. Chociaż działa to tylko dla elementów iframe, które istniały na oryginalnej stronie, ponieważ po raz pierwszy zostały zapytane, a nie te, które są ładowane dynamicznie, np. przez JavaScript.
  • Pozwól, aby strona ładowała się normalnie, zwracając YES w zdarzeniu [webView: shouldStartLoadWithRequest: nawigacjiType:], a po zakończeniu ładowania sprawdź, czy adres URL WebView został zmieniony, czy nie ... jeśli to oznacza, że ​​był przekierowaniem strony jeśli nie, prawdopodobnie oznacza to, że został załadowany element iframe.
  • Przy użyciu JavaScriptu przesłonię ustawienie właściwości window.location, aby uruchomić własny kod, zanim zmieni on położenie okna. Mógłbym wtedy komunikować się z Objective-C, aby dać mu znać, że następny ładunek będzie faktycznie przekierowaniem. Czy jest to jednak jedyny sposób na przekierowanie w JavaScript?

Jaki jest najlepszy sposób na zrobienie tego? Czy możesz wymyślić jakieś sposoby, o których nie myślałem? Czy iframes ma specjalne wydarzenie/właściwość, którą mógłbym manipulować JavaScriptem, aby mi pomóc?

Dzięki

Aktualizacja: To nie jest tak proste, jak to tylko sprawdzenie navigationType. Chociaż kliknięcie linku w celu otwarcia nowej strony pojawi się jako navigationType = 0, przekierowanie JavaScript (zmieniające window.location) pojawi się jako navigationType = 5. Obciążenie iframe pojawi się również jako navigationType = 5. Tak więc, gdy navigationType = 5, nie wiesz, czy cała strona zmieniła adresy URL za pomocą JavaScriptu, czy jest to po prostu element ładujący, który ładuje się na tej samej stronie.

+1

Tak jak FYI, należy unikać odnosząc się do Apple wymienione rodzaje ich wartości całkowite - przykład navigationType == 5. Zamiast tego powinieneś w kodzie odwoływać się do nich po imieniu, np. UIWebViewNavigationTypeInne. Czy kompilator sprowadza go do zwykłej starej liczby całkowitej? Tak. Ale robienie tego we właściwy sposób pozostawia izolację, jeśli zmienia kolejność ich wyliczonych typów lub określa konkretną liczbę całkowitą w przyszłości. –

Odpowiedz

6

Właśnie stosowali tę metodę:

Niech strona załadowała się zwykle wracając Yes w [Webview: shouldStartLoadWithRequest: navigationType:] zdarzeń, a gdy to się robi ładowania, sprawdzić, czy adres URL Webview zmieniła czy nie ... jeśli to oznacza, że ​​jest to przekierowanie strony, jeśli nie, prawdopodobnie oznacza to, że został załadowany element iframe.

2

Pomyślnie skorzystałem z pola "referer" HTTP (rzeczywisty nagłówek jest błędnie napisany), aby to wykryć.Powinien to być adres URL strony głównej (dostępnej z widoku) lub coś innego - prawdopodobnie ramka.

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

To nie działa w dzisiejszych czasach. Brak nagłówka referer. Otrzymuję: { Accept = "text/html, application/xhtml + xml, application/xml; q = 0.9, */*; q = 0.8"; "User-Agent" = "Mozilla/5.0 (iPhone, CPU iPhone OS 6_1 jak Mac OS X) AppleWebKit/536.26 (KHTML, jak 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

jedyna przykra odpowiedź – Fattie

Powiązane problemy