Sự kiện thay đổi kích thước cửa sổ trong JavaScript
Làm thế nào để tôi có thể kết nối vào sự kiện thay đổi kích thước cửa sổ trình duyệt?
Có một cách sử dụng jQuery để lắng nghe các sự kiện thay đổi kích thước nhưng tôi thích không thêm nó vào dự án của mình chỉ để đáp ứng yêu cầu này.
Câu trả lời #1
Thực tiễn tốt nhất là thêm vào sự kiện thay vì thay thế nó:
window.addEventListener('resize', function(event) {
...
}, true);
Một lựa chọn thay thế là tạo một bộ xử lý duy nhất cho sự kiện DOM (nhưng chỉ có thể có một), ví dụ.
window.onresize = function(event) {
...
};
jQuery có thể thực hiện một số công việc để đảm bảo rằng sự kiện thay đổi kích thước được kích hoạt nhất quán trên tất cả các trình duyệt, nhưng tôi không chắc liệu có trình duyệt nào khác biệt không, nhưng tôi khuyến khích bạn thử nghiệm trên Firefox, Safari và IE.
Câu trả lời #2
Trước hết, tôi biết phương thức addEventListener đã được đề cập trong các bình luận bên trên, nhưng tôi không thấy bất kỳ mã nào. Vì đây là cách tiếp cận được ưu tiên, nên đây là nó:
window.addEventListener('resize', function(event){
// do stuff here
});
Đây là một mẫu hoạt động.
Câu trả lời #3
Không bao giờ ghi đè hàm window.onresize.
Thay vào đó, tạo một hàm để thêm một Trình Nghe Sự Kiện vào đối tượng hoặc phần tử. Điều này kiểm tra và trong trường hợp các trình nghe không hoạt động, thì nó ghi đè hàm của đối tượng như một biện pháp cuối cùng. Đây là phương pháp được ưa chuộng được sử dụng trong các thư viện như jQuery.
object: đối tượng phần tử hoặc cửa sổ
type: resize, scroll (loại sự kiện)
callback: tham chiếu hàm
var addEvent = function(object, type, callback) {
if (object == null || typeof(object) == 'undefined') return;
if (object.addEventListener) {
object.addEventListener(type, callback, false);
} else if (object.attachEvent) {
object.attachEvent("on" + type, callback);
} else {
object["on"+type] = callback;
}
};
Sau đó sử dụng như sau:
addEvent(window, "resize", function_reference);
hoặc với một hàm ẩn danh:
addEvent(window, "resize", function(event) {
console.log('resized');
});
Câu trả lời #4
Giải pháp cho 2018+:
Bạn nên sử dụng ResizeObserver. Đây là một giải pháp gốc của trình duyệt và có hiệu suất tốt hơn nhiều so với việc sử dụng sự kiện resize. Ngoài ra, nó không chỉ hỗ trợ sự kiện trên document mà còn trên các elements tùy ý.
var ro = new ResizeObserver( entries => { for (let entry of entries) { const cr = entry.contentRect; console.log('Element:', entry.target); console.log(`Element size: ${cr.width}px x ${cr.height}px`); console.log(`Element padding: ${cr.top}px ; ${cr.left}px`); } }); // Observe one or multiple elements ro.observe(someElement);
Hiện tại, Firefox, Chrome, Safari và Edge hỗ trợ nó. Đối với các trình duyệt khác (và cũ hơn), bạn phải sử dụng một polyfill.
Câu trả lời #5
Sự kiện thay đổi kích thước không bao giờ nên được sử dụng trực tiếp vì nó được kích hoạt liên tục khi chúng ta thay đổi kích thước.
Sử dụng hàm debounce để giảm bớt các lần gọi vượt mức.
window.addEventListener('resize',debounce(handler, delay, immediate),false);Đây là một debounce phổ biến đang lan truyền trên mạng, mặc dù hãy tìm kiếm những phiên bản tiên tiến hơn như được giới thiệu trong lodash.
const debounce = (func, wait, immediate) => {
var timeout;
return () => {
const context = this, args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Điều này có thể được sử dụng như sau...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
Nó sẽ không bao giờ kích hoạt hơn một lần mỗi 200ms.
Để thay đổi hướng di động, hãy sử dụng:
window.addEventListener('orientationchange', () => console.log('hello'), false);
Đây là một thư viện nhỏ mà tôi đã làm để xử lý việc này một cách gọn gàng.
Câu trả lời số 6
Tôi thực sự tin rằng câu trả lời đúng đã được @Alex V cung cấp, tuy nhiên câu trả lời đó cần được hiện đại hóa một chút vì nó đã hơn năm năm tuổi.
Có hai vấn đề chính:
Không bao giờ sử dụng
objectlàm tên tham số. Đây là một từ khóa được bảo lưu. Nói như vậy, hàm do @Alex V cung cấp sẽ không hoạt động trongchế độ nghiêm ngặt.Hàm
addEventdo @Alex V cung cấp không trả vềđối tượng sự kiệnnếu phương thứcaddEventListenerđược sử dụng. Một tham số khác nên được thêm vào hàmaddEventđể cho phép điều này.
LƯU Ý: Tham số mới của addEvent đã được làm tùy chọn để việc chuyển sang phiên bản hàm mới này sẽ không làm hỏng bất kỳ lần gọi nào trước đó của hàm này. Tất cả các cách sử dụng cũ sẽ được hỗ trợ.
Đây là hàm addEvent được cập nhật với những thay đổi này:
/*
function: addEvent
@param: obj (Object)(Required)
- The object which you wish
to attach your event to.
@param: type (String)(Required)
- The type of event you
wish to establish.
@param: callback (Function)(Required)
- The method you wish
to be called by your
event listener.
@param: eventReturn (Boolean)(Optional)
- Whether you want the
event object returned
to your callback method.
*/
var addEvent = function(obj, type, callback, eventReturn)
{
if(obj == null || typeof obj === 'undefined')
return;
if(obj.addEventListener)
obj.addEventListener(type, callback, eventReturn ? true : false);
else if(obj.attachEvent)
obj.attachEvent("on" + type, callback);
else
obj["on" + type] = callback;
};
Một ví dụ gọi đến hàm addEvent mới:
var watch = function(evt)
{
/*
Older browser versions may return evt.srcElement
Newer browser versions should return evt.currentTarget
*/
var dimensions = {
height: (evt.srcElement || evt.currentTarget).innerHeight,
width: (evt.srcElement || evt.currentTarget).innerWidth
};
};
addEvent(window, 'resize', watch, true);
