เหตุการณ์การปรับขนาดหน้าต่างข้ามเบราว์เซอร์ - JavaScript / jQuery


240

อะไรคือวิธีที่ถูกต้อง (ทันสมัย) สำหรับการแตะที่หน้าต่างเพื่อปรับขนาดเหตุการณ์ที่ทำงานใน Firefox, WebKitและ Internet Explorer

และคุณสามารถเปิด / ปิดแถบเลื่อนทั้งสองได้หรือไม่


ฉันก็กำลังพิจารณาเรื่องนี้เช่นกัน ฉันต้องการลองใช้วิธีแก้ปัญหาที่นำเสนอที่นี่ แต่ฉันกลัวว่าฉันไม่เข้าใจไวยากรณ์: $ (หน้าต่าง) นั่นเป็นสิ่งที่เฉพาะเจาะจงสำหรับ jQuery หรือไม่?
Byff

1
โดยใช่ใช่ $ (หน้าต่าง) เป็นโครงสร้าง jQuery window.onresize เทียบเท่าใน JavaScript ดิบ
Andrew Hedges

การสาธิตนี้อาจช่วยให้ทุกคนทดสอบกับเบราว์เซอร์ทั้งหมดjsfiddle.net/subodhghulaxe/bHQV5/2
Subodh Ghulaxe

window.dispatchEvent(new Event('resize')); stackoverflow.com/questions/1818474/…
Dylan Valade

บน Opera บนมือถือจะมีการเรียกใช้แต่ละครั้งที่แถบด้านบน (เบราว์เซอร์ UI) แสดง / ซ่อน
psur

คำตอบ:


367

jQuery มีวิธีการในตัวสำหรับสิ่งนี้:

$(window).resize(function () { /* do something */ });

เพื่อการตอบสนองของ UI คุณอาจพิจารณาใช้ setTimeout เพื่อเรียกรหัสของคุณหลังจากผ่านไปหลายมิลลิวินาทีดังที่แสดงในตัวอย่างต่อไปนี้ซึ่งได้รับแรงบันดาลใจจากสิ่งนี้ :

function doSomething() {
    alert("I'm done resizing for the moment");
};

var resizeTimer;
$(window).resize(function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(doSomething, 100);
});

34
เหตุใดเหตุการณ์นี้จึงไม่เริ่มทำงานเมื่อหน้าต่างขยายเป็นปุ่มเต็มหน้าจอ
Sly

2
@Sly สำหรับฉันมันใช้งานได้ใน Safari, Chrome และ Mozilla บน Mac เบราว์เซอร์ใดที่คุณใช้
Mark Vital

2
@Sly:$('.button').on({ click: function(){ /* your code */ $(window).trigger('resize') })
Zack Zatkin-Gold

6
Elijah นี่คือ JavaScript สิ่งที่คุณเขียนไม่ถูกต้อง (ยกเว้นกรณีหนึ่งกรณีเมื่อคุณกำลังสร้างใหม่)
Yoh Suzuki

3
เป็นมูลค่าการกล่าวขวัญว่าฟังก์ชั่น jQuery นี้ "เพิ่ม" ฟังก์ชั่นการโทรไปยังรายการปัจจุบันของฟังก์ชั่นที่ควรจะเรียกว่าในการปรับขนาดหน้าต่าง มันไม่ได้เขียนทับเหตุการณ์ที่มีอยู่ที่กำหนดไว้ในปัจจุบันในการปรับขนาดหน้าต่าง
RTF

48
$(window).bind('resize', function () { 

    alert('resize');

});

4
ฉันชอบวิธีการเชื่อมโยงเนื่องจากวิธีการปรับขนาด () เป็นจริงทางลัดสำหรับวิธีการเชื่อมโยงเต็มรูปแบบและฉันมักจะพบว่ามักจะมีตัวจัดการเหตุการณ์มากกว่าหนึ่งตัวที่ฉันควรใช้กับองค์ประกอบ
Mike Kormendy

@Mike - ไม่เพียงแค่นั้น แต่ฉันเดาว่าวิธีการปรับขนาดนั้นไม่มีวิธี "unbind" ในกรณีที่คุณต้องการลบ listener "ผูก" เป็นวิธีที่จะไปแน่นอน!
เชน

43

นี่คือวิธีการที่ไม่ใช่ jQuery ของการแตะลงในเหตุการณ์การปรับขนาด:

window.addEventListener('resize', function(event){
  // do stuff here
});

มันทำงานบนเบราว์เซอร์ที่ทันสมัยทั้งหมด มันไม่ได้ช่วยอะไรคุณเลย นี่คือตัวอย่างของการใช้งานจริง


วิธีนี้จะไม่ทำงานใน IE รุ่นที่แก้ไขพร้อมการรองรับ IE dom: stackoverflow.com/questions/6927637/…
Sergey

1
> มันไม่ได้เร่งความเร็วอะไรสำหรับคุณ คุณช่วยอธิบายรายละเอียดได้ไหม? สิ่งที่ควร / จะเร่งความเร็ว? มันเกี่ยวข้องกับเหตุการณ์ที่เกิดขึ้นหลายครั้งติดต่อกันหรือไม่?
josinalvo

@josinalvo โดยทั่วไปเมื่อคุณกำลังฟังเหตุการณ์ที่เกิดไฟไหม้มากคุณจะต้องการdebounce (เช่น lodash)ดังนั้นคุณจะไม่ทำให้เกิดปัญหาคอขวดในโปรแกรมของคุณ
Jondlm

17

ขออภัยที่จะเปิดกระทู้เก่า แต่ถ้ามีคนไม่ต้องการใช้ jQuery คุณสามารถใช้สิ่งนี้:

function foo(){....};
window.onresize=foo;

8
เพิ่งทราบว่าสิ่งนี้จะปิดบังตัวจัดการที่มีอยู่ที่อาจถูกผูกไว้กับ window.onresize หากสคริปต์ของคุณต้องใช้ระบบนิเวศร่วมกับสคริปต์อื่นคุณไม่ควรถือว่าสคริปต์ของคุณเป็นเพียงโปรแกรมเดียวที่ต้องการปรับขนาดหน้าต่าง ถ้าคุณไม่สามารถใช้เฟรมเวิร์กเช่น jQuery คุณควรพิจารณาอย่างน้อยก็คว้าหน้าต่างที่มีอยู่เปิดใช้งานและเพิ่ม handler ของคุณไปยังส่วนท้ายของมันแทนที่จะปิดบังมัน
Tom Auger

2
@TomAuger "อย่างน้อยคุณควรพิจารณาคว้าหน้าต่างที่มีอยู่ทำการตรวจสอบและเพิ่มตัวจัดการของคุณไปยังจุดสิ้นสุดของมัน" - คุณอาจหมายถึงสิ่งที่ตรงกันข้ามนั่นคือ "การเรียกตัวจัดการที่มีอยู่ในตอนท้ายของตัวจัดการ" ฉันอยากจะเห็นรหัสจาวาสคริปต์ที่จะเพิ่มบางอย่างลงในส่วนท้ายของฟังก์ชั่นที่มีอยู่แล้ว :-)
TMS

ฉันเห็นประเด็นของคุณแล้ว - ตัวจัดการ onResize ใหม่ของคุณต้องล้อม onResize ที่มีอยู่ อย่างไรก็ตามไม่จำเป็นต้องเรียกใช้ฟังก์ชันที่คุณต้องการเพิ่มใน onResize จนกระทั่งหลังจากเรียกใช้ตัวจัดการ onResize ดั้งเดิม ดังนั้นคุณยังสามารถมั่นใจได้ว่าฟังก์ชั่น onResize ใหม่ของคุณทำงานหลังจากฟังก์ชั่น onResize ดั้งเดิมซึ่งน่าจะดีกว่าการกลับด้าน
Tom Auger


5

การใช้ jQuery 1.9.1 ฉันเพิ่งค้นพบว่าแม้ว่าจะเหมือนกันในทางเทคนิค) * สิ่งนี้ไม่ทำงานใน IE10 (แต่ใน Firefox):

// did not work in IE10
$(function() {
    $(window).resize(CmsContent.adjustSize);
});

ขณะที่สิ่งนี้ใช้ได้กับเบราว์เซอร์ทั้งสอง:

// did work in IE10
$(function() {
    $(window).bind('resize', function() {
        CmsContent.adjustSize();
    };
});

แก้ไข:
) * ที่จริงไม่เหมือนกันในทางเทคนิคตามที่ระบุไว้และอธิบายในความคิดเห็นโดยWraithKennyและเฮนรี่ไบลท์


1
มีการเปลี่ยนแปลงสองอย่าง อันไหนมีผลกระทบ? ( .resize()เพื่อ.bind('resize')หรือเพิ่มฟังก์ชั่นที่ไม่ระบุชื่อฉันคิดว่ามันเป็นครั้งที่สอง)
WraithKenny

@WraithKenny จุดที่ดี เป็นอย่างดีอาจเป็นได้ว่าการเพิ่มฟังก์ชั่นที่ไม่ระบุชื่อเป็นสิ่งที่ทำให้มันทำงาน ฉันจำไม่ได้ถ้าฉันลอง
bassim

1
ในกรณีแรกที่adjustSizeวิธีการสูญเสียบริบทของthisในขณะที่สายที่สองCmsContent.adjustSize()รักษาคือthis this === CmsContentหากต้องการCmsContentอินสแตนซ์ในadjustSizeเมธอดดังนั้นเคสแรกจะล้มเหลว กรณีที่สองจะใช้งานได้กับการเรียกใช้ฟังก์ชันทุกประเภทดังนั้นจึงขอแนะนำให้ใช้ฟังก์ชันที่ไม่ระบุชื่อ
Henry Blyth

1
@ HenryBlyth ขอบคุณ! +1
bassim

4

jQueryให้$(window).resize()ฟังก์ชั่นโดยค่าเริ่มต้น:

<script type="text/javascript">
// function for resize of div/span elements
var $window = $( window ),
    $rightPanelData = $( '.rightPanelData' )
    $leftPanelData = $( '.leftPanelData' );

//jQuery window resize call/event
$window.resize(function resizeScreen() {
    // console.log('window is resizing');

    // here I am resizing my div class height
    $rightPanelData.css( 'height', $window.height() - 166 );
    $leftPanelData.css ( 'height', $window.height() - 236 );
});
</script> 

3

ฉันคิดว่าปลั๊กอิน jQuery "jQuery resize event" เป็นทางออกที่ดีที่สุดสำหรับการดูแลปริมาณงานเพื่อให้เหมือนกันในทุกเบราว์เซอร์ มันคล้ายกับคำตอบของ Andrews แต่ดีกว่าเนื่องจากคุณสามารถเชื่อมโยงเหตุการณ์การปรับขนาดกับองค์ประกอบ / ตัวเลือกที่เฉพาะเจาะจงเช่นเดียวกับทั้งหน้าต่าง มันเปิดโอกาสใหม่ในการเขียนโค้ดที่ชัดเจน

มีปลั๊กอินให้ใช้งาน ที่นี่

มีปัญหาด้านประสิทธิภาพหากคุณเพิ่มผู้ฟังจำนวนมาก แต่สำหรับกรณีการใช้งานส่วนใหญ่มันสมบูรณ์แบบ


0

ฉันคิดว่าคุณควรเพิ่มการควบคุมเพิ่มเติมนี้:

    var disableRes = false;
    var refreshWindow = function() {
        disableRes = false;
        location.reload();
    }
    var resizeTimer;
    if (disableRes == false) {
        jQuery(window).resize(function() {
            disableRes = true;
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout(refreshWindow, 1000);
        });
    }

0

หวังว่ามันจะช่วยใน jQuery

กำหนดฟังก์ชั่นก่อนหากมีฟังก์ชั่นที่มีอยู่ข้ามไปยังขั้นตอนต่อไป

 function someFun() {
 //use your code
 }

เบราว์เซอร์ที่ปรับขนาดการใช้งานเช่นนี้

 $(window).on('resize', function () {
    someFun();  //call your function.
 });

0

นอกจากฟังก์ชั่นปรับขนาดหน้าต่างที่กล่าวถึงมันเป็นสิ่งสำคัญที่จะต้องเข้าใจว่าเหตุการณ์การปรับขนาดไฟมากถ้าใช้โดยไม่ต้อง deboucing เหตุการณ์

Paul Irish มีฟังก์ชั่นที่ยอดเยี่ยมที่จะทำการปรับขนาดการโทรได้อย่างมาก แนะนำให้ใช้มาก ๆ ทำงานข้ามเบราว์เซอร์ ทดสอบใน IE8 เมื่อวันก่อนและทุกอย่างเรียบร้อย

http://www.paulirish.com/2009/throttled-smartresize-jquery-event-handler/

อย่าลืมดูตัวอย่างเพื่อดูความแตกต่าง

นี่คือฟังก์ชั่นเพื่อความสมบูรณ์

(function($,sr){

  // debouncing function from John Hann
  // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
  var debounce = function (func, threshold, execAsap) {
      var timeout;

      return function debounced () {
          var obj = this, args = arguments;
          function delayed () {
              if (!execAsap)
                  func.apply(obj, args);
              timeout = null;
          };

          if (timeout)
              clearTimeout(timeout);
          else if (execAsap)
              func.apply(obj, args);

          timeout = setTimeout(delayed, threshold || 100);
      };
  }
  // smartresize 
  jQuery.fn[sr] = function(fn){  return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };

})(jQuery,'smartresize');


// usage:
$(window).smartresize(function(){
  // code that takes it easy...
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.