자바 스크립트 창 크기 조정 이벤트


616

브라우저 창 크기 조정 이벤트에 어떻게 연결할 수 있습니까?

거기에 크기 조정 이벤트를 수신의의 jQuery 방법은 하지만 난 그냥이 하나 개의 요구 사항에 대한 내 프로젝트에 그것을 가지고하지 않으려는 것입니다.


8
모두 감사합니다. IE에 신경 쓰지 않고 휴대 전화의 오페라 크기 조정에 대해 더 많이 생각하고있었습니다.
Dead account

답변:


641

jQuery는 표준 resizeDOM 이벤트를 래핑하고 있습니다 .

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

jQuery 모든 브라우저에서 resize 이벤트가 일관되게 발생하도록하기 위해 몇 가지 작업을 수행 할 수 있지만 브라우저가 다른지 확실하지 않지만 Firefox, Safari 및 IE에서 테스트하는 것이 좋습니다.


226
이 방법을 사용하면 잠재적 인 문제 중 하나는 이벤트를 재정의하므로 여러 작업을 이벤트에 첨부 할 수 없다는 것입니다. addEventListener / attachEvent 콤보는 자바 스크립트가 페이지에서 실행될 수있는 다른 스크립트와 친숙해 지도록하는 가장 좋은 방법입니다.
MyItchyChin 2016 년

4
var onresize = window.onresize; window.onresize = function (event) {if (typeof onresize === 'function') onresize (); / ** ... * /}
SubOne

230
window.addEventListener('resize', function(){}, true);
WebWanderer

16
@SubOne은 어떻게해야하는지에 대한 완벽한 예입니다.
유진 Pankov

28
ECMAScript를 6 : window.onresize = () => { /* code */ };이상 :window.addEventListener('resize', () => { /* code */ });
Derk 월 Speelman

560

먼저 addEventListener위의 주석에서 방법이 언급되었지만 코드는 보지 못했습니다. 선호되는 접근 방식이므로 다음과 같습니다.

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

다음은 작동하는 샘플 입니다.


63
이것은 가장 간단한 대답입니다.
jacoviza

7
window.onresize 이벤트를 덮어 쓰지 않기 때문에 가장 좋은 대답처럼 들립니다. :-)
James Harrington

27
이 예에서와 같이 많은 사람들이 익명 이벤트 리스너를 추가 할 수 있지만이 방법은 그것 수 있기 때문에, 정말 좋은 방법이 아닙니다 불가능 나중에이 리스너를 제거 할 수 있습니다. 어쨌든 웹 페이지는 수명이 짧았 기 때문에 문제가되지 않았지만, 오늘날 AJAX와 RIA 및 SPA의 시대는 하나가되고 있습니다. 이벤트 리스너 라이프 사이클을 관리 할 방법이 필요합니다. 따라서 리스너 함수를 별도의 함수로 분리하여 나중에 제거 할 수 있도록하는 것이 removeEventListener좋습니다.
Stijn de Witt

6
왜 할 수있는 모든 보풀이없는이 같은 모든 사람의 대답
quemeful

2
나는 Stijn de Witt와 quemeful의 대답 모두에 진실이 있다고 생각합니다. 때로는 이벤트 리스너를 제거하는 것이 중요하지만 그렇지 않은 경우 위의 예와 같이 추가 코드를 모두 추가하는 것은 불필요하며 부풀어 가독성이 떨어질 수 있습니다. 내 의견으로는 청취자를 제거해야 할 이유를 생각하지 않으면이 방법이 가장 좋습니다. 필요한 경우 언제든지 나중에 다시 쓸 수 있습니다. 내 경험상 이러한 요구는 특정 상황에서만 발생합니다.
cazort

525

window.onresize 함수를 재정의하지 마십시오.

대신, 객체 또는 요소에 이벤트 리스너를 추가하는 함수를 작성하십시오. 리스너가 작동하지 않는지 확인한 다음 마지막 수단으로 객체의 기능을 재정의합니다. 이것은 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');
});

100
이것은 받아 들여진 대답이어야합니다. onresize를 재정의하는 것은 나쁜 습관입니다.
Tiberiu-Ionuț Stan

8
아, 모든 여분의 null 검사는 무엇입니까? IE 4.5 등에서 작업하려고합니까?
FlavorScape

1
그리고 창 크기 조정 이벤트를 수신하기 위해이 함수를 어떻게 호출합니까? 방법은 다음과 같습니다. addEvent (window, "resize", function_reference); :)
oabarca

6
IE 11부터는 attachEvent더 이상 지원되지 않습니다. 미래에 선호되는 방법은 addEventListener입니다.
Luke

6
주의하십시오 elem == undefined. "정의되지 않은"은 로컬로 다른 것으로 정의 될 수 있습니다. stackoverflow.com/questions/8175673/…
누가

32

크기 조정 이벤트는 크기가 조정될 때 계속 발생하므로 직접 사용해서는 안됩니다.

디 바운스 기능을 사용하여 초과 통화를 완화하십시오.

window.addEventListener('resize',debounce(handler, delay, immediate),false);

그물에 떠 다니는 일반적인 디 바운스가 있지만, lodash에서 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);

200ms마다 한 번 이상 발사되지 않습니다.

모바일 방향 변경의 경우 다음을 사용하십시오.

window.addEventListener('orientationchange', () => console.log('hello'), false);

여기의 작은 도서관 나는 깔끔하게이 돌봐 함께 넣어.


debounce (이전에는 시간 초과를 사용하여 저항했지만 귀중한 개념 / 기능으로 보입니다), lodash (개인적으로 확신하지는 않지만) 및 addEvent를 폴백으로 사용할 지에 대한 모호성을 해결합니다. 대해 addEventListener (이전의 대답은 정말 명시 적으로에 대한 의견 제시하지 않는 때문)
wunth

5
당신이 ES6이 FUNC 표기법을 화살표를 사용하고 참고로하기 때문에, 내부 기능의 요구가 없습니다 (...arguments) => {...}(또는 ...args덜 혼란) arguments변수를 더 이상 사용할 수 그들의 범위입니다.
coderatchet

나는 스 니펫이 내 코드가 아니라는 것을 잘 알고 있습니다. 그것은 단지 예일뿐입니다.
frontsideup

큰 대답은 크기 조정과 관련된 성능 문제를 해결해야합니다! 디 바운싱은 옵션이며, 다른 하나는 간단한 조절입니다 ( "단계"에서 UI 크기를 조정해야하는 경우 갈 수 있습니다). 참조 bencentra.com/code/2015/02/27/optimizing-window-resize.html 예제
로빈 METRAL에게

24

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 을 사용해야합니다 .


2020 년 imo에서 아직도 가장 좋은 대답
Jesse Reza Khorasanee


16

나는 @Alex V가 정답을 이미 제공했다고 생각하지만 5 년이 넘었으므로 현대화해야합니다.

두 가지 주요 문제가 있습니다.

  1. object매개 변수 이름으로 사용하지 마십시오 . 예약어입니다. @Alex V에서 제공하는 기능은에서 ​​작동하지 않습니다 strict mode.

  2. addEvent@ 알렉스 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);

2017 년에 attachEvent가 더 이상 관련이 없다고 주장합니다.
Vlad Nicula

@VladNicula 동의하지만이 답변은 2 살입니다.
WebWanderer

12

http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html 에서 내 블로그 게시물을 참조 해 주셔서 감사합니다 .

표준 창 크기 조정 이벤트에 연결할 수는 있지만 IE에서는 이벤트가 X마다 한 번씩 발생하고 Y 축 이동마다 한 번씩 발생하여 많은 이벤트가 발생하여 성능이 저하 될 수 있음을 알 수 있습니다 렌더링이 집중적 인 작업 인 경우 사이트에 영향을 미칩니다.

내 방법에는 후속 이벤트에서 취소되는 짧은 시간 초과가 포함되어 있으므로 사용자가 창 크기 조정을 완료 할 때까지 이벤트가 코드로 버블 링되지 않습니다.


7
window.onresize = function() {
    // your code
};

22
위에서 언급 한 많은 의견에서 알 수 있듯이 onresize 함수를 덮어 쓰지 않는 것이 가장 좋습니다. 오히려 새로운 이벤트를 추가하십시오. Jondlm의 답변을 참조하십시오.
Luke

6

다음 블로그 게시물이 유용 할 수 있습니다. 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);
}

6
이것은 ASP.NET 응용 프로그램에만 적용됩니다
Evgeny Gorb

2

위에서 언급 한 솔루션은 창과 창의 크기를 조정하기 만하면 작동합니다. 그러나 크기 조정을 하위 요소로 전파하려면 이벤트를 직접 전파해야합니다. 이를 수행하는 예제 코드는 다음과 같습니다.

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();

resize 이벤트의 첫 번째 Arg로 전달되는 이벤트 객체에서 예를 들면 다음과 같습니다.

var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
  ...
  event.preventDefault();
});

1
<script language="javascript">
    window.onresize = function() {
    document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
} 

</script>

1
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_];
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.