UIWebView: когда страница действительно заканчивала загрузку?

Мне нужно знать, когда веб-страница полностью загружена UIWebView. Я имею в виду, действительно, полностью, когда все переадресации завершены, и динамически загруженный контент готов. Я попытался вставить javascript (запрос для document.readyState == 'complete' ), но это не кажется очень надежным.

Может быть, событие из частного api, которое принесет мне результат?

Я искал ответ для этого, и я получил эту идею от вопроса Себастьяна. Как-то это работает для меня, возможно, это будет для тех, кто сталкивается с этой проблемой.

Я устанавливаю делегат в UIWebView и в webViewDidFinishLoad, я обнаруживаю, что веб-просмотр действительно завершил загрузку, выполнив Javascript.

 - (void)webViewDidFinishLoad:(UIWebView *)webView { if ([[webView stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]) { // UIWebView object has fully loaded. } } 

Мое решение:

 - (void)webViewDidFinishLoad:(UIWebView *)webView { if (!webView.isLoading) { // Tada } } 

Способность UIWebView выполнять Javascript не зависит от того, загружена ли страница или нет. Его возможное использование stringByEvaluatingJavaScriptFromString: выполнить Javascript, прежде чем вы даже сделаете вызов для загрузки страницы в UIWebView в первую очередь или без загрузки страницы вообще.

Поэтому я не могу понять, как принимается ответ в этой ссылке: webViewDidFinishLoad: стрельба слишком скоро? потому что вызов любого Javascript вообще ничего не говорит вам (если они называют какой-то интересный Javascript, который контролирует dom, например, они не упоминают об этом, и если бы они были, потому что это было важно).

Вы можете вызвать Javascript, который, например, проверяет состояние dom или состояние загруженной страницы и сообщает, что обратно к вызывающему коду, однако, если он сообщает, что страница еще не загружена, что вы делаете? – вам придется называть это снова немного позже, но сколько позже, когда, где, как, как часто … Опрос обычно никогда не является хорошим решением ни для чего.

Единственный способ узнать, когда страница полностью загружена, быть точным и контролировать то, что именно она делает, – подключить слушателей событий JavaScript на загружаемую страницу и заставить их вызвать ваш shouldStartLoadWithRequest: с некоторыми проприетарными URL-адрес. Например, вы можете создать функцию JS для прослушивания загрузки windows или события, подготовленного dom, и т. Д. В зависимости от того, нужно ли вам знать, когда загружена страница, или только что загрузили дом и т. Д. В зависимости от ваших потребностей.

Если веб-страница не ваша, вы можете поместить этот javascript в файл и ввести его на каждую загружаемую страницу.

Как создать javascript-прослушиватели событий – стандартный javascript, ничего особенного для iOS, например, здесь JavaScript, чтобы определить, когда dom загрузился в форму, которая может быть введена на страницу загрузки из UIWebView, а затем привести к вызов toStartLoadWithRequest: (это вызовет shouldStartLoadWithRequestwhen: dom завершил загрузку, которая до отображения полного содержимого страницы, чтобы обнаружить это, просто измените прослушиватель событий).

 var script = document.createElement('script'); script.type = 'text/javascript'; script.text = function DOMReady() { document.location.href = "mydomain://DOMIsReady"; } function addScript() { document.getElementsByTagName('head')[0].appendChild(script); document.addEventListener('DOMContentLoaded', DOMReady, false); } addScript(); 

Ответ Мартина Х на правильном пути, но его все равно можно уволить несколько раз.

Что вам нужно сделать, это добавить слушателя Javascript onLoad на страницу и следить за тем, вставили ли вы слушателя:

 #define kPageLoadedFunction @"page_loaded" #define kPageLoadedStatusVar @"page_status" #define kPageLoadedScheme @"pageloaded" - (NSString*) javascriptOnLoadCompletionHandler { return [NSString stringWithFormat:@"var %[email protected] = function() {window.location.href = '%[email protected]:' + window.location.href; window.%[email protected] = 'loaded'}; \ \ if (window.attachEvent) {window.attachEvent('onload', %[email protected]);} \ else if (window.addEventListener) {window.addEventListener('load', %[email protected], false);} \ else {document.addEventListener('load', %[email protected], false);}",kPageLoadedFunction,kPageLoadedScheme,kPageLoadedStatusVar]; } - (BOOL) javascriptPageLoaded:(UIWebView*)browser { NSString* page_status = [browser stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"window.%@",kPageLoadedStatusVar]]; return [page_status isEqualToString:@"loaded"]; } - (void)webViewDidFinishLoad:(UIWebView *)browser { if(!_js_load_indicator_inserted && ![self javascriptPageLoaded:browser]) { _js_load_indicator_inserted = YES; [browser stringByEvaluatingJavaScriptFromString:[self javascriptOnLoadCompletionHandler]]; } else _js_load_indicator_inserted = NO; } 

Когда страница будет завершена, слушатель Javascript инициирует загрузку новой страницы URL-адреса с помощью pageloaded: . Затем вам просто нужно обновить shouldStartLoadWithRequest чтобы найти эту схему URL:

 - (BOOL)webView:(UIWebView *)browser shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if([request.URL.scheme isEqualToString:kPageLoadedScheme]){ _js_load_indicator_inserted = NO; NSString* loaded_url = [request.URL absoluteString]; loaded_url = [loaded_url substringFromIndex:[loaded_url rangeOfString:@":"].location+1];  return NO; } } 

Вы также можете использовать принятый ответ здесь: UIWebView – как определить последнее сообщение webViewDidFinishLoad? …

В принципе, используйте свойство valuProgress, и когда это достигает 100, страница закончила загрузку … См. Это руководство для справки.

Хотя он использует частную структуру, в соответствии с руководством есть некоторые приложения в App Store, которые используют его …

Сделайте свой controller просмотра делегатом UIWebView. (Вы можете сделать это в Interface Builder или используя этот код в методе viewDidLoad:

 [self.myWebView setDelegate:self]; 

Затем используйте метод, описанный в принятом ответе здесь: webViewDidFinishLoad: стрельба слишком скоро? ,

Код:

 -(void) webViewDidFinishLoad:(UIWebView *)webView { NSString *javaScript = @"function myFunction(){return 1+1;}"; [webView stringByEvaluatingJavaScriptFromString:javaScript]; //Has fully loaded, do whatever you want here } 

WKWebView вызывает делегат didFinish когда DOM readyState является interactive , что слишком рано для веб-страниц, загруженных javascripts. Нам нужно дождаться complete состояния. Я создал такой код:

 func waitUntilFullyLoaded(_ completionHandler: @escaping () -> Void) { webView.evaluateJavaScript("document.readyState === 'complete'") { (evaluation, _) in if let fullyLoaded = evaluation as? Bool { if !fullyLoaded { DDLogInfo("Webview not fully loaded yet...") DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: { self.waitUntilFullyLoaded(completionHandler) }) } else { DDLogInfo("Webview fully loaded!") completionHandler() } } } } 

а потом:

 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { DDLogInfo("Webview claims that is fully loaded") waitUntilFullyLoaded { [weak self] in guard let unwrappedSelf = self else { return } unwrappedSelf.activityIndicator?.stopAnimating() unwrappedSelf.isFullLoaded = true } } 

Вот упрощенная версия ответа @jasonjwwilliams.

 #define JAVASCRIPT_TEST_VARIBLE @"window.IOSVariable" #define JAVASCRIPT_TEST_FUNCTION @"IOSFunction" #define LOAD_COMPLETED @"loaded" // Put this in your init method // In Javascript, first define the function, then attach it as a listener. _javascriptListener = [NSString stringWithFormat: @"function %@() {\ %@ = '%@';\ };\ window.addEventListener(\"load\", %@, false);", JAVASCRIPT_TEST_FUNCTION, JAVASCRIPT_TEST_VARIBLE, LOAD_COMPLETED, JAVASCRIPT_TEST_FUNCTION]; // Then use this: - (void)webViewDidFinishLoad:(UIWebView *)webView; { // Only want to attach the listener and function once. if (_javascriptListener) { [_webView stringByEvaluatingJavaScriptFromString:_javascriptListener]; _javascriptListener = nil; } if ([[webView stringByEvaluatingJavaScriptFromString:JAVASCRIPT_TEST_VARIBLE] isEqualToString:LOAD_COMPLETED]) { NSLog(@"UIWebView object has fully loaded."); } } 

Благодаря JavaScript новые ресурсы и новая графика могут быть загружены навсегда – определение того, когда загрузка «сделана», для страницы с достаточной извращенностью, будет означать решение проблемы остановки . Вы действительно не можете знать, когда страница загружена.

Если вы можете, просто отобразите страницу или ее изображение и используйте webViewDidLoad для обновления изображения и дайте пользователю возможность отключить или отключить.

попробуйте что-то вроде https://github.com/Buza/uiwebview-load-completion-tracker, это помогло мне загрузить Google Street View

  • Как вызвать метод Objective C из Javascript и отправить данные в Javascript в iOS?
  • iPhone UIWebView локальных ресурсов с использованием Javascript и обработки onorientationChange
  • Запуск функции shouldStartLoadWithRequest с несколькими вызовами window.location.href
  • Как отобразить вызов аутентификации в UIWebView?
  • Удалить UIWebView Shadow?
  • Клавиатура не отображается при нажатии текстового поля в UIWebView
  • как увеличить размер шрифта в UIWebView
  • Как очистить кеш UIWebView?
  • iPhone - UIWebview - Получите URL-адрес ссылки, нажатой
  • Возвратитесь к поведению приложения после разговора по телефону в собственном коде, чем UIWebView
  • UIMoviePlayerControllerDidEnterFullscreenNotification не работает в iOS8
  • Давайте будем гением компьютера.