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




webview swift 4 (8)

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

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


Сделайте свой контроллер просмотра делегатом 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
}

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

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

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

Единственный способ узнать, когда страница полностью загружена, быть точным и контролировать то, что именно она делает, - подключить слушателей событий JavaScript на загружаемую страницу и заставить их вызвать ваш shouldStartLoadWithRequest: с некоторыми проприетарными URL-адрес. Например, вы можете создать функцию JS для прослушивания загрузки окна или события, подготовленного 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();

Вот упрощенная версия ответа @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.");
    }
}

Мое решение:

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


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

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


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

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

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


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

Что вам нужно сделать, это добавить слушателя 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:<URL that actually finished> . Затем вам просто нужно обновить 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];

        <DO STUFF THAT SHOULD HAPPEN WHEN THE PAGE LOAD FINISHES.>

        return NO;
    }
}