wykonać funkcję po całkowitym załadowaniu strony


121

Używam następującego kodu do wykonywania niektórych instrukcji po załadowaniu strony.

 <script type="text/javascript">
    window.onload = function () { 

        newInvite();
        document.ag.src="b.jpg";
    }
</script>

Ale ten kod nie działa poprawnie. Funkcja jest wywoływana nawet wtedy, gdy ładowane są niektóre obrazy lub elementy. Chcę wywołać funkcję, że strona jest ładowana całkowicie.


1
Czy możesz dodać demo na JSFiddle.net ?
Jakiś facet

2
Czy mógłbyś użyć jQuery? Jeśli tak, spróbuj$(window).load()
Matt Hintzke

Tak, czy mógłbyś dokładnie wyjaśnić, co nie działa prawidłowo? Czy pojawia się błąd, a może wywołujesz alertfunkcję przed ponownym rysowaniem okna (dzięki czemu wygląda tak, jakby była wywoływana przed załadowaniem)? Kod wygląda dobrze, a zmuszanie użytkowników do pobierania dużych bibliotek prawdopodobnie nie rozwiąże tego problemu ani nie ułatwi diagnozy.
Jeffrey Sweeney


Kiedy mówię, że nie działa, mam na myśli to, że funkcja jest uruchamiana, nawet jeśli niektóre obrazy są ładowane.
Neeraj Kumar

Odpowiedzi:


166

to może działać dla Ciebie:

document.addEventListener('DOMContentLoaded', function() {
   // your code here
}, false);

lub jeśli czujesz się komfortowo z jquery,

$(document).ready(function(){
// your code
});

$(document).ready()uruchamia się w DOMContentLoaded, ale to zdarzenie nie jest wywoływane konsekwentnie między przeglądarkami. Dlatego jQuery najprawdopodobniej zaimplementuje kilka ciężkich obejść, aby obsługiwać wszystkie przeglądarki. A to bardzo utrudni „dokładne” symulowanie zachowania przy użyciu zwykłego JavaScript (ale oczywiście nie jest to niemożliwe).

jak zasugerowali Jeffrey Sweeney i J Torres, myślę, że lepiej jest mieć setTimeoutfunkcję przed uruchomieniem funkcji, jak poniżej:

setTimeout(function(){
 //your code here
}, 3000);

12
jQuery readynie zrobi tego, o co prosił OP. readyuruchamia się, gdy DOM ładuje się, a nie po załadowaniu elementów. loadzapali się po zakończeniu ładowania / renderowania elementów.
Jaime Torres

Wygląda na to, że OP chce, aby wszystkie elementy zostały załadowane w całości, a nie tylko HTML.
Jeffrey Sweeney

3
@shreedhar lub mógłby użyć odpowiedniego narzędzia do pracy ( load).
Jaime Torres

14
setTimeoutto zły pomysł. Polega na ładowaniu strony poniżej 3 sekund (lub n sekund, w zależności od wybranej wartości). Jeśli ładowanie trwa dłużej, nie będzie działać, a jeśli strona ładuje się szybciej, będzie musiała czekać bez powodu.
JJJ,

1
@ChristianMatthew its useCapture Jeśli true, useCapture wskazuje, że użytkownik chce zainicjować przechwytywanie. Po zainicjowaniu przechwytywania wszystkie zdarzenia określonego typu będą wysyłane do zarejestrowanego nasłuchiwania przed wysłaniem do jakichkolwiek EventTargets znajdujących się pod nim w drzewie DOM. Zdarzenia, które są propagowane w górę przez drzewo, nie wywołają odbiornika wyznaczonego do przechwytywania. Zobacz zdarzenia DOM Level 3, aby uzyskać szczegółowe wyjaśnienie.
Shreedhar

52

JavaScript

document.addEventListener('readystatechange', event => { 

    // When HTML/DOM elements are ready:
    if (event.target.readyState === "interactive") {   //does same as:  ..addEventListener("DOMContentLoaded"..
        alert("hi 1");
    }

    // When window loaded ( external resources are loaded too- `css`,`src`, etc...) 
    if (event.target.readyState === "complete") {
        alert("hi 2");
    }
});

to samo dla jQuery:

$(document).ready(function() {   //same as: $(function() { 
     alert("hi 1");
});

$(window).load(function() {
     alert("hi 2");
});





UWAGA: - Nie używaj poniższego znacznika (ponieważ zastępuje on inne deklaracje tego samego rodzaju):

document.onreadystatechange = ...

1
czy ta przeglądarka internetowa jest obsługiwana
bluejayke

Ta odpowiedź jest znacznie lepsza niż inne. +1
Xydez

Bardzo dobrze! Dzięki.
Farzin Kanzi

34

Jeśli możesz używać jQuery, spójrz na load . Następnie możesz ustawić funkcję tak, aby działała po zakończeniu ładowania elementu.

Weźmy na przykład pod uwagę stronę z prostym obrazem:

<img src="book.png" alt="Book" id="book" />

Program obsługi zdarzeń można powiązać z obrazem:

$('#book').load(function() {
  // Handler for .load() called.
});

Jeśli chcesz załadować wszystkie elementy w bieżącym oknie, możesz użyć

$(window).load(function () {
  // run code
});

1
Czy loadmetoda jQuery nie wiąże po prostu funkcji ze zdarzeniem load przy użyciu JavaScript? Czym miałoby się to różnić od tego, co już robi PO?
Alex Kalicki

@AlexKalicki AFAIK nie byłoby inaczej, poza tym, że jQuery może używać addEventListenerzamiast wiązać onloadwłaściwość DOM0 .
Alnitak

@AlexKalicki Nie mogę powiedzieć, że używa dokładnie tej samej funkcjonalności, ale zgodnie z dokumentacją jQuery dba o to, aby wszystkie elementy, w tym obrazy, zostały załadowane przed tym uruchomieniem. Byłbym skłonny wierzyć, że w takim przypadku byłaby dodatkowa logika i nie mam powodu, aby nie wierzyć dokumentacji, chociaż nigdy nie natknąłem się na ten sam problem, który zgłasza PO.
Jaime Torres

4
Począwszy od wersji JQuery 1.8 .load jest przestarzały. źródło
Adonis K. Kakoulidis,

1
Najlepsze rozwiązanie na to pytanie.
Roberto Sepúlveda Bravo

29

Jestem trochę zdezorientowany, co masz na myśli mówiąc o zakończeniu ładowania strony, „wczytywaniu DOM” czy „ładowaniu treści”? W html załadowanie strony może wywołać zdarzenie po dwóch typach zdarzeń.

  1. Ładowanie DOM: które zapewniają ładowanie całego drzewa DOM od początku do końca. Ale nie upewnij się, że ładujesz zawartość referencyjną. Załóżmy, że dodałeś obrazy za pomocą imgtagów, więc to zdarzenie zapewnia, że ​​wszystkie imgzaładowane, ale żadne obrazy nie zostały poprawnie załadowane lub nie. Aby otrzymać to wydarzenie należy napisać w następujący sposób:

    document.addEventListener('DOMContentLoaded', function() {
       // your code here
    }, false);
    

    Lub używając jQuery:

    $(document).ready(function(){
    // your code
    });
    
  2. Po DOM i załadowaniu treści: które wskazują również ładowanie DOM i zawartości. Zapewni to nie tylko imgtag, ale także załadowanie wszystkich obrazów lub innych względnych treści. Aby otrzymać to wydarzenie należy napisać w następujący sposób:

    window.addEventListener('load', function() {...})

    Lub używając jQuery:

    $(window).on('load', function() {
     console.log('All assets are loaded')
    })

2
To jedyna odpowiedź, która daje rozwiązanie inne niż jQuery dla PO, z jasnym wyjaśnieniem
Velojet

Moduł DOMContentLoadedobsługi zdarzeń @Hanif wydaje się nie robić nic dla mnie, ale loadrobi.
Brandon Benefield

1
Czy dwa ostatnie przykłady nie wymagają średników na końcu wierszy?
R. Navega,

11

Jeśli chcesz wywołać funkcję js na swojej stronie html, użyj zdarzenia onload. Zdarzenie onload występuje, gdy agent użytkownika zakończy ładowanie okna lub wszystkich ramek w FRAMESET. Ten atrybut może być używany z elementami BODY i FRAMESET.

<body onload="callFunction();">
....
</body>

7

W ten sposób możesz obsłużyć oba przypadki - czy strona jest już załadowana, czy nie:

document.onreadystatechange = function(){
    if (document.readyState === "complete") {
       myFunction();
    }
    else {
       window.onload = function () {
          myFunction();
       };
    };
}

3

Alternatywnie możesz spróbować poniżej.

$(window).bind("load", function() { 
// code here });

To działa w każdym przypadku. Będzie to wywoływane tylko wtedy, gdy zostanie załadowana cała strona.


3

O ile wiem, najlepiej jest założyć

window.addEventListener('load', function() {
    console.log('All assets loaded')
});

Pierwsza odpowiedź dotycząca korzystania z tego DOMContentLoadedzdarzenia to krok wstecz, ponieważ DOM zostanie załadowany przed załadowaniem wszystkich zasobów.

Inne odpowiedzi zalecają, setTimeoutktórym zdecydowanie się sprzeciwiam, ponieważ jest to całkowicie subiektywne dla wydajności urządzenia klienta i szybkości połączenia sieciowego. Jeśli ktoś jest w powolnej sieci i / lub ma wolny procesor, załadowanie strony może zająć od kilku do kilkudziesięciu sekund, więc nie można było przewidzieć, ile czasu setTimeoutbędzie to wymagało.

A jeśli chodzi o readystatechangeto, odpala zawsze, gdy się readyStatezmieni, co według MDN będzie jeszcze przed loadwydarzeniem.

Kompletny

Stan wskazuje, że nastąpi uruchomienie zdarzenia obciążenia.


2
window.onload = () => {
  // run in onload
  setTimeout(() => {
    // onload finished.
    // and execute some code here like stat performance.
  }, 10)
}

2
Chociaż ten fragment kodu może być rozwiązaniem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod.
yivi

@yivi, jeśli to nie jest automatyczna wiadomość: dla każdego jest dość oczywiste, co oznacza ten kod, zwłaszcza że w kodzie są komentarze ...
bluejayke


1

Jeśli korzystasz już z jQuery, możesz spróbować tego:

$(window).bind("load", function() {
   // code here
});

4
Bezużyteczne bez wyjaśnienia.
Daniel W.

1

Mogę powiedzieć, że najlepszą odpowiedzią, jaką znalazłem, jest umieszczenie skryptu „sterownika” tuż po </body>poleceniu. Jest to najłatwiejsze i prawdopodobnie bardziej uniwersalne niż niektóre powyższe rozwiązania.

Plan: Na mojej stronie jest tabela. Piszę stronę z tabelą do przeglądarki, a następnie sortuję ją za pomocą JS. Użytkownik może go użyć, klikając nagłówki kolumn.

Po zakończeniu </tbody>polecenia w tabeli i zakończeniu treści, używam następującego wiersza, aby wywołać sortowanie JS, aby posortować tabelę według kolumny 3. Otrzymałem skrypt sortowania z sieci, więc nie jest tutaj odtwarzany. Przynajmniej przez następny rok można to zobaczyć w działaniu, w tym w JS, pod adresem static29.ILikeTheInternet.com. Kliknij „tutaj” u dołu strony. Spowoduje to wyświetlenie kolejnej strony z tabelą i skryptami. Możesz zobaczyć, jak umieszcza dane, a następnie szybko je posortować. Muszę to trochę przyspieszyć, ale podstawy są już dostępne.

</tbody></body><script type='text/javascript'>sortNum(3);</script></html>

MakerMikey


0

Spróbuj tego jQuery :

$(function() {
 // Handler for .ready() called.
});

1
jQuery readynie zrobi tego, o co prosił OP. readyuruchamia się, gdy DOM ładuje się, a nie po załadowaniu elementów. loadzapali się po zakończeniu ładowania / renderowania elementów.
Jaime Torres

0

wywołać funkcję po upływie określonego czasu ładowania strony

setTimeout(function() {
   var val = $('.GridStyle tr:nth-child(2) td:nth-child(4)').text();
	for(var i, j = 0; i = ddl2.options[j]; j++) {
		if(i.text == val) {      
			ddl2.selectedIndex = i.index;
			break;
		}
	} 
}, 1000);


0

Zwykle używam następującego wzoru, aby sprawdzić, czy dokument został w pełni załadowany. Funkcja zwraca Obietnicę (jeśli potrzebujesz obsługi IE, dołącz polifill ), która zostanie rozwiązana po zakończeniu ładowania dokumentu. Używa setIntervalpod spodem, ponieważ podobna implementacja setTimeoutmogłaby skutkować bardzo głębokim stosem.

function getDocReadyPromise()
{
  function promiseDocReady(resolve)
  {
    function checkDocReady()
    {
      if (document.readyState === "complete")
      {
        clearInterval(intervalDocReady);
        resolve();
      }
    }
    var intervalDocReady = setInterval(checkDocReady, 10);
  }
  return new Promise(promiseDocReady);
}

Oczywiście, jeśli nie musisz wspierać IE:

const getDocReadyPromise = () =>
{
  const promiseDocReady = (resolve) =>
  {
    const checkDocReady = () =>
      ((document.readyState === "complete") && (clearInterval(intervalDocReady) || resolve()));
    let intervalDocReady = setInterval(checkDocReady, 10);
  }
  return new Promise(promiseDocReady);
}

Dzięki tej funkcji możesz wykonać następujące czynności:

getDocReadyPromise().then(whatIveBeenWaitingToDo);

-1

Używam komponentów internetowych, więc działa dla mnie:

document.addEventListener('WebComponentsReady', function() {
       document.querySelector('your-element').show();
});

-3

Umieść swój skrypt po zakończeniu tagu body ... to działa ...

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.