2012-02-03 27 views
28

Vì vậy, tôi cần phải biết chiều rộng của một phần tử với javascript, vấn đề tôi có là chức năng cháy quá sớm và chiều rộng thay đổi khi css được tottally áp dụng. Như tôi đã hiểu, hàm $ (document) .ready() đã được kích hoạt khi tài liệu được hoàn thành, nhưng nó dường như không hoạt động như thế.

Anyways, tôi chắc chắn rằng với mã vấn đề của tôi sẽ được hiểu (điều này là một ví dụ đơn giản):

<html> 
<head> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
    <link href='http://fonts.googleapis.com/css?family=Parisienne' rel='stylesheet' type='text/css'> 

    <style type="text/css"> 
     #target { 
      font-family: 'Parisienne', cursive; 
      float: left; 
     } 
    </style> 
</head> 
<body> 
    <div id="target">Element</div> 
</body> 
</html> 

<script type="text/javascript"> 
    $(document).ready(function(){ 
     console.debug($('#target').outerWidth()); 
     alert('hold on'); 
     console.debug($('#target').outerWidth()); 
    }); 
</script> 

Tôi muốn biết chiều rộng của div #target, vấn đề là mã được thực hiện trước khi cảnh báo đưa ra một kết quả khác với kết quả sau, có lẽ vì phông chữ không được tải đầy đủ và nó đo div với phông chữ mặc định.

Nó hoạt động như tôi mong đợi trong Google Chrome, nhưng nó không có trên IE và Firefox.

+0

Tôi có thể khẳng định 2013/11/24 rằng vấn đề này vẫn còn tồn tại trên JQuery 2.x khi bạn nhấn nút refresh của trình duyệt. Truy cập [fiddle] này (http://jsfiddle.net/jLDbX/). Khi bạn lần đầu tiên tải fiddle, mọi thứ sẽ hoạt động tốt cho hầu hết các lần. Nó cũng hoạt động nếu bạn đặt con trỏ chuột vào URL và nhấn enter. Nhưng mọi thứ sẽ đi vào địa ngục nếu bạn nhấp vào nút làm mới hoặc nhấn * CTRL + R *. –

+0

Tôi đã cố gắng thực hiện một chốt "đếm ngược" để đo chiều rộng và chiều cao chỉ khi cả hai cửa sổ tải bắn và khi phông chữ phụ thuộc đã hoàn thành cháy. Xem liệu nó có giúp ích không: [http://jsfiddle.net/jLDbX/1/](http://jsfiddle.net/jLDbX/1/). Trong câu chuyện này, mọi thứ dường như đang hoạt động tốt. Nhưng trong ứng dụng thế giới thực của tôi, tôi vẫn gặp lỗi. Đối với bạn mặc dù, nó có thể làm việc. –

Trả lời

58

Nếu bạn dựa vào nội dung bên ngoài được đã nạp (ví dụ hình ảnh, phông chữ), bạn cần phải sử dụng các sự kiện window.load

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

Hành vi của những sự kiện được mô tả trong this article.

+5

Hai năm sau, vẫn hữu ích! – statue

+5

Trong JQuery 3.0, bạn nên sử dụng cú pháp '$ (cửa sổ) .on ('load', function() { });' vì $ (window) .load() không được chấp nhận. –

+0

@ AlexH, điểm tốt. '$ (window) .load()' không được chấp nhận trong jQuery 1.8. Hơn nữa, nó là khó hiểu vì có hai phương thức '.load()' trong jQuery (trước khi xử lý sự kiện đã được gỡ bỏ). – ryanpcmcquen

9

Trích OP:

"Như tôi hiểu, các $(document).ready() chức năng đã bị sa thải khi tài liệu được hoàn thành,"

$(document).ready() cháy khi DOM ("mô hình đối tượng tài liệu ") được tải đầy đủ và sẵn sàng để được thao tác. DOM không giống như "tài liệu".

W3C - DOM Frequently Asked Questions

Bạn có thể thử $(window).load() chức năng thay vì ...

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

Nó sẽ chờ đợi cho tất cả các tài sản của trang (như hình ảnh và phông chữ, vv) để nạp đầy trước khi bắn.

3

Hàm jQuery .ready() sẽ kích hoạt ngay khi DOM hoàn tất. Điều đó không có nghĩa là tất cả các tài sản (như hình ảnh, CSS vv) đã được tải tại thời điểm đó và do đó kích thước của các phần tử có thể thay đổi.

Sử dụng $ (cửa sổ) .load() nếu bạn cần kích thước của phần tử.

1

Bạn có thể sử dụng $(window).load(), nhưng điều đó sẽ chờ tất cả các tài nguyên (ví dụ: hình ảnh, v.v.). Nếu bạn chỉ muốn đợi tải phông chữ, bạn có thể thử một cái gì đó như thế này:

<script type="text/javascript"> 
    var isFontLoaded = false; 
    var isDocumentReady = false; 
    $("link[href*=fonts.googleapis.com]").load(function() { 
     isFontLoaded = true; 
     if (isDocumentReady) { 
      init(); 
     } 
    }); 
    $(document).ready(function() { 
     isDocumentReady = true; 
     if (isFontLoaded) { 
      init(); 
     } 
    }); 
    function init() { 
     // do something with $('#target').outerWidth() 
    } 
</script> 

Tuyên bố từ chối: Tôi không hoàn toàn chắc chắn điều này sẽ hoạt động. Sự kiện onload <link> có thể kích hoạt ngay khi biểu định kiểu được phân tích cú pháp, nhưng trước khi tài nguyên bên ngoài của nó được tải xuống. Có thể bạn có thể thêm <img src="fontFile.eot" /> ẩn và đặt trình xử lý tải lên của bạn lên hình ảnh thay thế.

2

Sự kiện "sẵn sàng" kích hoạt khi DOM được tải có nghĩa là khi có thể làm việc an toàn với đánh dấu.

Để chờ tất cả nội dung được tải (css, hình ảnh, javascript bên ngoài ...), bạn muốn sử dụng sự kiện tải.

$(window).load(function() { 
    ... 
}); 
1

Tôi đã hoàn toàn, lặp lại thấy cùng một vấn đề trong IE9 và IE10. Đám cháy cuộc gọi jquery ready() và một trong số < div> của tôi không tồn tại. Nếu tôi phát hiện và sau đó gọi lại sau một thời gian chờ ngắn() nó hoạt động tốt.

Giải pháp của tôi, chỉ để được an toàn, đã hai lần:

  1. Nối một < script> window.fullyLoaded = true; </script> ở phần cuối của tài liệu sau đó kiểm tra cho rằng biến trong() gọi lại sẵn sàng, VÀ

  2. Kiểm tra nếu $ ('# lastElementInTheDocument') chiều dài.> 0

Vâng, Tôi nhận ra rằng đây là những hacks khó chịu. Tuy nhiên, khi ready() không hoạt động như mong đợi, một số công việc xung quanh là cần thiết!

Như một sang một bên, giải pháp "đúng" có thể liên quan đến việc đặt $ .holdReady trong tiêu đề và xóa nó ở cuối tài liệu. Nhưng tất nhiên, giải pháp thực sự đúng là sẵn sàng() để làm việc.

+0

Tôi nghĩ rằng tôi cũng thấy hành vi này. Có lẽ giải pháp là đặt lệnh document.ready ở cuối trang, mà dường như là một thực tế phổ biến hơn trong những ngày này. Tôi thấy sự cố này, nhưng hiện tại tôi có lệnh document.ready của mình trong thẻ . – hairbo

1

Vấn đề $ (tài liệu) .ready() cháy quá sớm đôi khi có thể xảy ra vì bạn đã khai báo chức năng jQuery onReady không đúng cách.

Nếu gặp vấn đề, hãy chắc chắn chức năng của bạn được khai báo chính xác như vậy:

$(document).ready(function() 
{ 
    // put your code here for what you want to do when the page loads. 
}); 

Ví dụ, nếu bạn đã quên phần chức năng ẩn danh, mã sẽ vẫn chạy, nhưng nó sẽ chạy "ra theo thứ tự ".

console.log('1'); 
$(document).ready() 
{ 
    console.log('3'); 
} 
console.log('2'); 

điều này sẽ ra

1 
3 
2 
Các vấn đề liên quan