ฉันจะขอปรับขนาดเหตุการณ์หน้าต่างปรับขนาดเบราว์เซอร์ได้อย่างไร
มีวิธี jQuery ในการฟังสำหรับปรับขนาดกิจกรรมแต่ฉันไม่ต้องการที่จะนำมาไว้ในโครงการของฉันสำหรับข้อกำหนดนี้
ฉันจะขอปรับขนาดเหตุการณ์หน้าต่างปรับขนาดเบราว์เซอร์ได้อย่างไร
มีวิธี jQuery ในการฟังสำหรับปรับขนาดกิจกรรมแต่ฉันไม่ต้องการที่จะนำมาไว้ในโครงการของฉันสำหรับข้อกำหนดนี้
คำตอบ:
jQuery เป็นเพียงห่อresize
เหตุการณ์ DOM มาตรฐานเช่น
window.onresize = function(event) {
...
};
jQuery อาจทำงานเพื่อให้แน่ใจว่าเหตุการณ์การปรับขนาดได้รับการยิงอย่างสม่ำเสมอในเบราว์เซอร์ทั้งหมด แต่ฉันไม่แน่ใจว่าเบราว์เซอร์ใด ๆ ที่แตกต่างกัน แต่ฉันขอแนะนำให้คุณทดสอบใน Firefox, Safari และ IE
window.addEventListener('resize', function(){}, true);
window.onresize = () => { /* code */ };
หรือดีกว่า:window.addEventListener('resize', () => { /* code */ });
ก่อนอื่นฉันรู้ว่าaddEventListener
วิธีการดังกล่าวได้รับการกล่าวถึงในความคิดเห็นข้างต้น แต่ฉันไม่เห็นรหัสใด ๆ เนื่องจากเป็นวิธีที่ต้องการนี่คือ:
window.addEventListener('resize', function(event){
// do stuff here
});
removeEventListener
ดังนั้นมันจะดีกว่าที่จะออกมาจากปัจจัยที่ฟังก์ชั่นเข้ากับฟังก์ชั่นที่แยกต่างหากเพื่อที่จะสามารถลบออกได้ในภายหลังด้วย
อย่าแทนที่ฟังก์ชั่น window.onresize
ให้สร้างฟังก์ชันเพื่อเพิ่ม Event Listener ให้กับวัตถุหรือองค์ประกอบแทน สิ่งนี้จะตรวจสอบและใส่หีบที่ผู้ฟังไม่ทำงานจากนั้นจะแทนที่ฟังก์ชั่นของวัตถุเป็นทางเลือกสุดท้าย นี่เป็นวิธีที่ต้องการใช้ในไลบรารีเช่น jQuery
object
: องค์ประกอบหรือวัตถุหน้าต่าง
type
: ปรับขนาดเลื่อน (ประเภทเหตุการณ์)
callback
: การอ้างอิงฟังก์ชั่น
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;
}
};
จากนั้นใช้เป็นเช่นนี้:
addEvent(window, "resize", function_reference);
หรือด้วยฟังก์ชั่นที่ไม่ระบุชื่อ:
addEvent(window, "resize", function(event) {
console.log('resized');
});
attachEvent
ไม่รองรับอีกต่อไป addEventListener
วิธีที่แนะนำสำหรับอนาคตคือ
elem == undefined
โปรดใช้ความระมัดระวังด้วย เป็นไปได้ (แม้ว่าไม่น่าเป็นไปได้) ว่า "undefined" ถูกกำหนดแบบโลคัลเป็นอย่างอื่น stackoverflow.com/questions/8175673/…
ไม่ควรใช้เหตุการณ์การปรับขนาดโดยตรงเนื่องจากถูกปรับขนาดอย่างต่อเนื่องเมื่อเราปรับขนาด
ใช้ฟังก์ชั่น debounce เพื่อลดการโทรเกิน
window.addEventListener('resize',debounce(handler, delay, immediate),false);
นี่คือ debounce ทั่วไปที่ลอยอยู่ในเน็ตแม้ว่าจะมองหาตัวละครที่ล้ำหน้ากว่านี้ในฐานะ featuerd
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);
};
};
สามารถใช้งานได้เช่นนี้ ...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
มันจะไม่ยิงมากกว่าหนึ่งครั้งทุกๆ 200 มิลลิวินาที
สำหรับการเปลี่ยนการวางแนวมือถือใช้:
window.addEventListener('orientationchange', () => console.log('hello'), false);
นี่คือห้องสมุดเล็ก ๆ ที่ฉันรวบรวมดูแลอย่างเรียบร้อย
(...arguments) => {...}
(หรือ...args
สำหรับความสับสนน้อยลง) เนื่องจากarguments
ตัวแปรไม่สามารถใช้งานได้อีกต่อไป
คำตอบสำหรับ 2018+:
คุณควรใช้ResizeObserver มันเป็นวิธีแก้ปัญหาเบราว์เซอร์ที่มีประสิทธิภาพดีกว่าการใช้resize
เหตุการณ์ นอกจากนี้มันไม่เพียง แต่สนับสนุนเหตุการณ์ที่แต่ยังเกี่ยวกับพลdocument
elements
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);
ปัจจุบันFirefox, Chrome และ Safari สนับสนุนมัน เบราว์เซอร์อื่น ๆ (และเก่า) คุณต้องใช้polyfill
ฉันเชื่อว่าคำตอบที่ถูกต้องนั้นได้รับการจัดหาโดย @Alex V แล้ว แต่คำตอบนั้นจำเป็นต้องได้รับการปรับปรุงให้ทันสมัยเนื่องจากอายุมากกว่าห้าปีในขณะนี้
มีสองประเด็นหลัก:
ห้ามใช้object
เป็นชื่อพารามิเตอร์ มันเป็นคำที่ reservered ด้วยความเป็นอยู่นี้กล่าวว่า @ Alex V strict mode
ของฟังก์ชั่นที่ให้บริการจะไม่ทำงานใน
addEvent
ฟังก์ชั่นให้โดย @ Alex V ไม่กลับevent object
ถ้าaddEventListener
วิธีการที่ใช้ ควรเพิ่มพารามิเตอร์อื่นลงในaddEvent
ฟังก์ชันเพื่ออนุญาตสิ่งนี้
หมายเหตุ: พารามิเตอร์ใหม่ที่addEvent
ถูกสร้างขึ้นเป็นทางเลือกเพื่อให้การย้ายไปยังฟังก์ชันรุ่นใหม่นี้จะไม่ทำให้การเรียกใช้ฟังก์ชันนี้ก่อนหน้านี้แตก การใช้งานแบบดั้งเดิมทั้งหมดจะได้รับการสนับสนุน
นี่คือaddEvent
ฟังก์ชั่นที่ได้รับการอัพเดตพร้อมการเปลี่ยนแปลงเหล่านี้:
/*
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;
};
ตัวอย่างการเรียกใช้addEvent
ฟังก์ชันใหม่:
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);
ขอบคุณสำหรับการอ้างอิงโพสต์บล็อกของฉันที่http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html
ในขณะที่คุณสามารถเชื่อมต่อกับเหตุการณ์การปรับขนาดหน้าต่างมาตรฐานคุณจะพบว่าใน IE เหตุการณ์จะถูกยิงหนึ่งครั้งสำหรับทุก ๆ X และอีกครั้งสำหรับการเคลื่อนไหวแกน Y ทุกครั้งทำให้เกิดเหตุการณ์มากมายที่อาจมีประสิทธิภาพ ส่งผลกระทบต่อเว็บไซต์ของคุณหากการแสดงผลเป็นงานที่ต้องทำมาก
วิธีการของฉันเกี่ยวข้องกับการหมดเวลาสั้น ๆ ที่ถูกยกเลิกในเหตุการณ์ที่ตามมาเพื่อให้เหตุการณ์ไม่ได้รับการขัดเกลารหัสของคุณจนกว่าผู้ใช้จะปรับขนาดหน้าต่างเสร็จสิ้น
window.onresize = function() {
// your code
};
โพสต์บล็อกต่อไปนี้อาจเป็นประโยชน์กับคุณ: การแก้ไขเหตุการณ์การปรับขนาดหน้าต่างใน IE
มันให้รหัสนี้:
Sys.Application.add_load(function(sender, args) { $addHandler(window, 'resize', window_resize); }); var resizeTimeoutId; function window_resize(e) { window.clearTimeout(resizeTimeoutId); resizeTimeoutId = window.setTimeout('doResizeCode();', 10); }
วิธีแก้ไขปัญหาที่กล่าวถึงข้างต้นจะใช้งานได้หากสิ่งที่คุณต้องการทำคือปรับขนาดหน้าต่างและหน้าต่างเท่านั้น อย่างไรก็ตามหากคุณต้องการปรับขนาดที่แพร่กระจายไปยังองค์ประกอบลูกคุณจะต้องเผยแพร่กิจกรรมด้วยตัวเอง นี่คือตัวอย่างรหัสที่จะทำ:
window.addEventListener("resize", function () {
var recResizeElement = function (root) {
Array.prototype.forEach.call(root.childNodes, function (el) {
var resizeEvent = document.createEvent("HTMLEvents");
resizeEvent.initEvent("resize", false, true);
var propagate = el.dispatchEvent(resizeEvent);
if (propagate)
recResizeElement(el);
});
};
recResizeElement(document.body);
});
โปรดทราบว่าองค์ประกอบลูกสามารถโทร
event.preventDefault();
บนวัตถุเหตุการณ์ที่ส่งผ่านเป็น Arg แรกของเหตุการณ์ปรับขนาด ตัวอย่างเช่น:
var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
...
event.preventDefault();
});
<script language="javascript">
window.onresize = function() {
document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
}
</script>
var EM = new events_managment();
EM.addEvent(window, 'resize', function(win,doc, event_){
console.log('resized');
//EM.removeEvent(win,doc, event_);
});
function events_managment(){
this.events = {};
this.addEvent = function(node, event_, func){
if(node.addEventListener){
if(event_ in this.events){
node.addEventListener(event_, function(){
func(node, event_);
this.events[event_](win_doc, event_);
}, true);
}else{
node.addEventListener(event_, function(){
func(node, event_);
}, true);
}
this.events[event_] = func;
}else if(node.attachEvent){
var ie_event = 'on' + event_;
if(ie_event in this.events){
node.attachEvent(ie_event, function(){
func(node, ie_event);
this.events[ie_event]();
});
}else{
node.attachEvent(ie_event, function(){
func(node, ie_event);
});
}
this.events[ie_event] = func;
}
}
this.removeEvent = function(node, event_){
if(node.removeEventListener){
node.removeEventListener(event_, this.events[event_], true);
this.events[event_] = null;
delete this.events[event_];
}else if(node.detachEvent){
node.detachEvent(event_, this.events[event_]);
this.events[event_] = null;
delete this.events[event_];
}
}
}