thực hiện chức năng sau khi tải xong trang


121

Tôi đang sử dụng mã sau để thực thi một số câu lệnh sau khi tải trang.

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

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

Nhưng mã này không hoạt động bình thường. Hàm được gọi ngay cả khi một số hình ảnh hoặc phần tử đang tải. Điều tôi muốn là gọi hàm trang được tải hoàn chỉnh.


1
Bạn có thể thêm bản demo trên JSFiddle.net không?
Some Guy

2
Bạn có thể sử dụng jQuery? Nếu vậy, hãy thử$(window).load()
Matt Hintzke 13/12/12

Có, bạn có thể giải thích chính xác những gì không hoạt động bình thường? Bạn gặp lỗi hoặc có lẽ bạn đang gọi một alerthàm trước khi cửa sổ vẽ lại (làm cho nó giống như được gọi trước khi tải)? Mã trông ổn và việc buộc người dùng tải xuống các thư viện lớn có thể sẽ không khắc phục được sự cố này hoặc giúp chẩn đoán dễ dàng hơn.
Jeffrey Sweeney


Khi tôi nói rằng nó không hoạt động, ý tôi là hàm được kích hoạt ngay cả khi một số hình ảnh đang được tải.
Neeraj Kumar

Câu trả lời:


166

điều này có thể làm việc cho bạn:

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

hoặc nếu bạn thoải mái với jquery,

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

$(document).ready()kích hoạt trên DOMContentLoaded, nhưng sự kiện này không được kích hoạt nhất quán giữa các trình duyệt. Đây là lý do tại sao jQuery có thể sẽ triển khai một số giải pháp thay thế nặng để hỗ trợ tất cả các trình duyệt. Và điều này sẽ làm cho rất khó để mô phỏng "chính xác" hành vi sử dụng Javascript thuần túy (nhưng tất nhiên không phải là không thể).

như Jeffrey Sweeney và J Torres đã đề xuất, tôi nghĩ tốt hơn hết là nên có một setTimeouthàm, trước khi kích hoạt hàm như dưới đây:

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

12
jQuery's readysẽ không làm những gì OP yêu cầu. readykích hoạt khi DOM tải, không phải sau khi các phần tử tải. loadsẽ kích hoạt sau khi các phần tử hoàn tất tải / kết xuất.
Jaime Torres

Có vẻ như OP muốn tất cả các phần tử được tải hoàn toàn, không chỉ HTML.
Jeffrey Sweeney

3
@shreedhar hoặc anh ấy có thể sử dụng công cụ phù hợp cho công việc ( load).
Jaime Torres

14
setTimeoutlà một ý tưởng tồi. Nó phụ thuộc vào việc tải trang dưới 3 giây (hoặc n giây tùy thuộc vào giá trị bạn chọn.) Nếu tải lâu hơn, nó sẽ không hoạt động và nếu trang tải nhanh hơn, nó sẽ không phải đợi lý do gì.
JJJ

1
@ChristianMatthew nó useCapture Nếu đúng, useCapture cho thấy mong muốn người dùng để bắt đầu chụp. Sau khi bắt đầu nắm bắt, tất cả các sự kiện thuộc loại được chỉ định sẽ được gửi đến trình nghe đã đăng ký trước khi được gửi đến bất kỳ Mục tiêu sự kiện nào bên dưới nó trong cây DOM. Các sự kiện đang sôi sục lên qua cây sẽ không kích hoạt người nghe được chỉ định sử dụng tính năng chụp. Xem Sự kiện DOM cấp 3 để có giải thích chi tiết.
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");
    }
});

tương tự cho jQuery:

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

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





LƯU Ý: - Không sử dụng đánh dấu bên dưới (vì nó ghi đè lên các khai báo cùng loại khác):

document.onreadystatechange = ...

1
được trình duyệt chéo này được hỗ trợ
bluejayke

Câu trả lời này tốt hơn nhiều so với những câu khác. +1
Xydez

Rất tốt! Cảm ơn.
Farzin Kanzi

34

Nếu bạn có thể sử dụng jQuery, hãy xem tải . Sau đó, bạn có thể đặt chức năng của mình để chạy sau khi phần tử của bạn tải xong.

Ví dụ: hãy xem xét một trang có hình ảnh đơn giản:

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

Trình xử lý sự kiện có thể được liên kết với hình ảnh:

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

Nếu bạn cần tất cả các phần tử trên cửa sổ hiện tại để tải, bạn có thể sử dụng

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

1
Không phải loadphương thức jQuery chỉ liên kết một hàm với sự kiện tải bằng Javascript? Điều này sẽ khác như thế nào so với những gì OP đã làm?
Alex Kalicki

@AlexKalicki AFAIK sẽ không có gì khác biệt, ngoại trừ việc jQuery có thể sử dụng addEventListenerthay vì ràng buộc thuộc tính DOM0 onload.
Alnitak

@AlexKalicki Tôi không thể nói rằng nó sử dụng cùng một chức năng, nhưng theo tài liệu, jQuery đảm bảo rằng tất cả các phần tử bao gồm cả hình ảnh được tải trước khi điều này kích hoạt. Tôi có xu hướng tin rằng sẽ có logic bổ sung nếu đúng như vậy, và tôi không có lý do gì để không tin vào tài liệu, mặc dù tôi chưa bao giờ gặp phải vấn đề tương tự mà OP đang báo cáo.
Jaime Torres

4
Kể từ JQuery v1.8, .load không được dùng nữa. nguồn
Adonis K. Kakoulidis

1
Giải pháp tốt nhất cho câu hỏi.
Roberto Sepúlveda Bravo

29

Tôi hơi nhầm lẫn rằng ý của bạn khi tải trang hoàn tất, "Tải DOM" hay "Tải nội dung" là gì? Trong một lần tải trang html có thể kích hoạt sự kiện sau sự kiện hai loại.

  1. Tải DOM: Đảm bảo toàn bộ cây DOM được tải bắt đầu kết thúc. Nhưng không đảm bảo tải nội dung tham khảo. Giả sử bạn đã thêm hình ảnh bằng các imgthẻ, vì vậy sự kiện này đảm bảo rằng tất cả imgcác hình ảnh được tải nhưng không có hình ảnh nào được tải đúng cách hay không. Để có được sự kiện này, bạn nên viết theo cách sau:

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

    Hoặc sử dụng jQuery:

    $(document).ready(function(){
    // your code
    });
  2. Sau DOM và Tải nội dung: Cho biết cả DOM và Tải nội dung. Nó sẽ đảm bảo không chỉ imggắn thẻ mà còn đảm bảo tất cả các hình ảnh hoặc nội dung tương đối khác được tải. Để có được sự kiện này, bạn nên viết theo cách sau:

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

    Hoặc sử dụng jQuery:

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

2
Đây là chỉ trả lời ở đây là đưa ra một giải pháp phi jQuery cho OP, với một lời giải thích rõ ràng
Velojet

Trình DOMContentLoadedxử lý sự kiện @Hanif dường như không làm được gì cho tôi nhưng loadcó.
Brandon Benefield

1
Hai ví dụ cuối cùng có cần dấu chấm phẩy ở cuối dòng không?
R. Navega

11

Nếu bạn muốn gọi một hàm js trong trang html của mình, hãy sử dụng sự kiện onload. Sự kiện tải xảy ra khi tác nhân người dùng tải xong một cửa sổ hoặc tất cả các khung trong FRAMESET. Thuộc tính này có thể được sử dụng với các phần tử BODY và ​​FRAMESET.

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

7

Bằng cách này, bạn có thể xử lý cả hai trường hợp - nếu trang đã được tải hoặc chưa:

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

3

Ngoài ra, bạn có thể thử bên dưới.

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

Điều này hoạt động trong mọi trường hợp. Điều này sẽ chỉ kích hoạt khi toàn bộ trang được tải.


3

Tốt nhất bạn nên sử dụng theo những gì tôi biết là sử dụng

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

Câu trả lời số 1 của việc sử dụng DOMContentLoadedsự kiện là một bước lùi vì DOM sẽ tải trước khi tất cả nội dung tải.

Các câu trả lời khác đề xuất setTimeoutmà tôi sẽ phản đối mạnh mẽ vì nó hoàn toàn chủ quan đối với hiệu suất thiết bị của khách hàng và tốc độ kết nối mạng. Nếu ai đó sử dụng mạng chậm và / hoặc có cpu chậm, một trang có thể mất vài đến hàng chục giây để tải, do đó bạn không thể dự đoán được setTimeoutsẽ cần bao nhiêu thời gian .

Đối với readystatechangenó, nó sẽ kích hoạt bất cứ khi nào các readyStatethay đổi mà theo MDN sẽ vẫn có trước loadsự kiện.

Hoàn thành

Trạng thái chỉ ra rằng sự kiện tải sắp kích hoạt.


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

2
Mặc dù đoạn mã này có thể là giải pháp, nhưng bao gồm lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
yivi

@yivi nếu đó không phải là một thông báo tự động: nó khá rõ ràng cho bất cứ ai điều đó có nghĩa mã, đặc biệt là kể từ khi có thảo luận trong các mã ..
bluejayke


1

Nếu bạn đã sử dụng jQuery, bạn có thể thử cách này:

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

4
Vô ích mà không cần giải thích.
Daniel W.

1

Tôi có thể nói với bạn rằng câu trả lời tốt nhất mà tôi tìm thấy là đặt một tập lệnh "trình điều khiển" ngay sau </body>lệnh. Đây là cách dễ nhất và có lẽ là phổ biến hơn một số giải pháp ở trên.

Kế hoạch: Trên trang của tôi là một cái bàn. Tôi viết trang có bảng ra trình duyệt, sau đó sắp xếp nó bằng JS. Người dùng có thể sử dụng nó bằng cách nhấp vào tiêu đề cột.

Sau khi kết thúc bảng, một </tbody>lệnh và phần nội dung được kết thúc, tôi sử dụng dòng sau để gọi JS sắp xếp để sắp xếp bảng theo cột 3. Tôi đã xóa tập lệnh sắp xếp khỏi web nên nó không được sao chép ở đây. Trong ít nhất năm tới, bạn có thể thấy điều này đang hoạt động, bao gồm cả JS, tại static29.ILikeTheInternet.com. Bấm vào "đây" ở cuối trang. Điều đó sẽ hiển thị một trang khác với bảng và các tập lệnh. Bạn có thể thấy nó sắp xếp dữ liệu sau đó nhanh chóng sắp xếp nó. Tôi cần tăng tốc một chút nhưng những điều cơ bản đã có ngay bây giờ.

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

MakerMikey


0

Hãy thử jQuery này :

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

1
jQuery's readysẽ không làm những gì OP yêu cầu. readykích hoạt khi DOM tải, không phải sau khi các phần tử tải. loadsẽ kích hoạt sau khi các phần tử hoàn tất tải / kết xuất.
Jaime Torres

0

gọi một hàm sau khi tải xong trang đã đặt hết thời gian

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

Tôi có xu hướng sử dụng mẫu sau để kiểm tra xem tài liệu đã hoàn tất tải chưa. Hàm trả về một Lời hứa (nếu bạn cần hỗ trợ IE, hãy bao gồm polyfill ) sẽ giải quyết khi tài liệu hoàn tất tải. Nó sử dụng setIntervalbên dưới vì việc triển khai tương tự với setTimeoutcó thể dẫn đến một ngăn xếp rất sâu.

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

Tất nhiên, nếu bạn không phải hỗ trợ IE:

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

Với chức năng đó, bạn có thể làm như sau:

getDocReadyPromise().then(whatIveBeenWaitingToDo);

-1

Tôi đang sử dụng các thành phần web để phù hợp với tôi:

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

-3

Đặt tập lệnh của bạn sau khi hoàn thành thẻ body ... nó hoạt động ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.