ブラウザウィンドウのサイズ変更イベントにフックするにはどうすればよいですか?
サイズ変更イベントをリッスンするjQueryの方法はありますが、この1つの要件のためだけに、プロジェクトにjQueryを組み込まないようにします。
ブラウザウィンドウのサイズ変更イベントにフックするにはどうすればよいですか?
サイズ変更イベントをリッスンするjQueryの方法はありますが、この1つの要件のためだけに、プロジェクトにjQueryを組み込まないようにします。
回答:
jQueryは標準のresize
DOMイベントをラップするだけです。
window.onresize = function(event) {
...
};
jQuery は、すべてのブラウザーで一貫してresizeイベントが発生するようにいくつかの作業を行う場合がありますが、ブラウザーのいずれかが異なるかどうかはわかりませんが、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関数をオーバーライドしないでください。
代わりに、オブジェクトまたは要素にイベントリスナーを追加する関数を作成します。これは、リスナーが機能しないことを確認し、その場合、最後の手段としてオブジェクトの機能をオーバーライドします。これは、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
。「可能性は低いですが」「未定義」がローカルで別のものとして定義されている可能性があります。stackoverflow.com/questions/8175673/…–
resizeイベントは、サイズ変更時に継続的に発生するため、直接使用しないでください。
デバウンス機能を使用して、過剰な呼び出しを軽減します。
window.addEventListener('resize',debounce(handler, delay, immediate),false);
これはネット上に浮かぶ一般的なデバウンスですが、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);
};
};
これは次のように使用できます...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
200ミリ秒に1回以上発砲することはありません。
モバイルの向きを変更するには、次を使用します。
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でサポートされています。他の(および古い)ブラウザーでは、ポリフィルを使用する必要があります。
正しい答えは@Alex Vによってすでに提供されていると私は確信していますが、答えは現在5年以上経過しているため、いくつかの近代化が必要です。
主な問題は2つあります。
object
パラメータ名として使用しないでください。予約語です。そのため、@ Alex Vが提供する関数はで機能しませんstrict mode
。
addEvent
@Alex Vによって提供される機能は返さないevent object
場合はaddEventListener
この方法が使用されています。addEvent
これを可能にするには、関数に別のパラメーターを追加する必要があります。
注:addEvent
この新しい関数バージョンに移行しても、この関数への以前の呼び出しが中断されないように、新しいパラメーターto はオプションになっています。すべてのレガシー使用がサポートされます。
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ごとに1回、Y軸の移動ごとに1回、イベントが発生します。その結果、大量のイベントが発生し、パフォーマンスが向上する場合がありますレンダリングが集中的なタスクである場合、サイトに影響を与えます。
私の方法は、ユーザーがウィンドウのサイズ変更を完了するまでイベントがコードにバブリングしないように、後続のイベントでキャンセルされる短いタイムアウトを含みます。
次のブログ投稿が役立つかもしれません: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();
resizeイベントの最初のArgとして渡されるイベントオブジェクト。例えば:
var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
...
event.preventDefault();
});
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_];
}
}
}