ご存知のように、Internet Explorerでは、ページ上の要素のサイズが変更されるとwindow.resizeイベントが発生します。高さやスタイルの割り当て/変更によってページ要素のサイズが変更されるかどうかは関係ありません。要素のサイズ変更がビューポート自体の寸法に影響を与えない場合でも、単に子要素を追加するなどして属性を指定します。
私のアプリケーションでは、これが厄介な再帰を引き起こしています。window.resizeハンドラーで<li>要素のサイズを変更し、window.resizeなどを再起動するからです。これもIEの問題です。
window.resizeがIEサイズ変更されているページの要素に応じて起動するのを防ぎますか?
JQueryを使用していることにも言及する必要があります。
私はあなたを助けるかもしれない別の問題を発見しました。
私はjQueryを使用していますが、window.resizeイベントを使用して、本文に追加されたdivを再配置する関数を呼び出しています。
これで、追加されたdivのLEFT cssプロパティを設定すると、window.resizeイベントがNO GOOD REASONのトリガーを取得します。
その結果、無限ループが発生し、window.resizeが何度もトリガーされます。
$(window).resize(function(){
var onResize = function(){
//The method which alter some css properties triggers
//window.resize again and it ends in an infinite loop
someMethod();
}
window.clearTimeout(resizeTimeout);
resizeTimeout = window.setTimeout(onResize, 10);
});
var winWidth = $(window).width(),
winHeight = $(window).height();
$(window).resize(function(){
var onResize = function(){
//The method which alter some css properties triggers
//window.resize again and it ends in an infinite loop
someMethod();
}
//New height and width
var winNewWidth = $(window).width(),
winNewHeight = $(window).height();
// compare the new height and width with old one
if(winWidth!=winNewWidth || winHeight!=winNewHeight){
window.clearTimeout(resizeTimeout);
resizeTimeout = window.setTimeout(onResize, 10);
}
//Update the width and height
winWidth = winNewWidth;
winHeight = winNewHeight;
});
したがって、基本的には、高さまたは幅が変更されたかどうかを確認します(実際にウィンドウでサイズを変更した場合にのみ発生します)。
これは私にとって理にかなっており、IE7以上で動作するようです:
//variables to confirm window height and width
var lastWindowHeight = $(window).height();
var lastWindowWidth = $(window).width();
$(window).resize(function() {
//confirm window was actually resized
if($(window).height()!=lastWindowHeight || $(window).width()!=lastWindowWidth){
//set this windows size
lastWindowHeight = $(window).height();
lastWindowWidth = $(window).width();
//call my function
myfunction();
}
});
サイズ変更リスナーを.one()
でバインドして、起動後に自身のバインドを解除します。その後、最後にサイズ変更リスナーを再バインドする限り、何でもできます。これを行う最も簡単な方法は、次のような匿名関数にサイズ変更リスナーを配置することです。
_var resizeListener = function(){
$(window).one("resize",function(){ //unbinds itself every time it fires
//resize things
setTimeout(resizeListener,100); //rebinds itself after 100ms
});
}
resizeListener();
_
技術的にはsetTimeout
をresizeListener()
の周りにラップする必要はありませんが、ジャストインケースとして、そしていくつかの余分な調整のためにそこに入れました。
サイズ変更機能のバインドを解除し、ページを再構築してから、サイズ変更機能を再度バインドすることで解決しました。
function rebuild() {
$(window).unbind('resize');
/* do stuff here */
$(window).bind('resize',rebuild);
}
$(window).bind('resize',rebuild);
編集
IE8ではバインドとバインド解除はうまくいきません。 MicrosoftはIE8を断念しましたが、これを試してみることもできます(テストされていません!)。
function rebuild(){
if(!window.resizing) return false;
window.resizing=true;
/* do stuff here */
window.resizing=false;
}
window.resizing=false;
document.body.onresize=rebuild;
@ AamirAfridi.comの答えは私の問題を解決しました。
そのようなことを解決するために共通の関数を書くことは良い考えです:
function onWindowResize(callback) {
var width = $(window).width(),
height = $(window).height();
$(window).resize(function() {
var newWidth = $(window).width(),
newHeight = $(window).height();
if (newWidth !== width || newHeight !== height) {
width = newWidth;
height = newHeight;
callback();
}
});
}
このように使用すれば、IE以降の異なる動作について心配する必要はありません。
onWindowResize(function() {
// do something
});
これを試すことができます:
コンストラクター:
this.clientWidth = null;
this.clientHeight = null;
一部の関数:
var clientWidth = window.innerWidth || document.documentElement.clientWidth;
var clientHeight = window.innerHeight || document.documentElement.clientHeight;
if (clientWidth != this.clientWidth || clientHeight != this.clientHeight ) {
this.clientWidth = clientWidth;
this.clientHeight = clientHeight;
... YOUR CODE ...
}
Internet Explorer、Chrome、Firefox、Opera、およびSafariの場合:
window.innerHeight - the inner height of the browser window
window.innerWidth - the inner width of the browser window
Internet Explorer 8、7、6、5の場合:
document.documentElement.clientHeight
document.documentElement.clientWidth
or
document.body.clientHeight
document.body.clientWidth
unbind
/bind
メソッドと遅延呼び出しの組み合わせ。 Internet Explorer 8以下で動作し、バージョン6および7で悪のループとハングを防ぎます。
function resizeViewport()
{
// Unbind and rebind only for IE < 9
var isOldIE = document.all && !document.getElementsByClassName;
if( isOldIE )
$(window).unbind( 'resize', resizeViewport );
// ...
if( isOldIE )
{
setTimeout(function(){
$(window).resize( resizeViewport );
}, 100);
}
}
$(window).resize( resizeViewport );
今日、私はこの問題に遭遇し、次の内容をグローバルに含まれるjavascriptファイルの先頭に置くことにしました。
var savedHeight = 0;
var savedWidth = 0;
Event.observe(window, 'resize', function (e) {
if (window.innerHeight == savedHeight &&
window.innerWidth == savedWidth) { e.stop(); }
savedHeight = window.innerHeight;
savedWidth = window.innerWidth;
});
ちなみに、これにはプロトタイプが必要です。
<pre>
var cont = 0;
var tmRsize = 100;
var lastWindowWidth = $(window).width();
var lastWindowHeight = $(window).height();
/*****redimensionamiento**********/
$(window).resize(function()
{
if($(window).width() != lastWindowWidth || $(window).height() != lastWindowHeight)
{
clearTimeout(this.id);
this.tiempo = tmRsize;
this.id = setTimeout(doResize, this.tiempo);
}
});
function doResize()
{
lastWindowWidth = $(window).width();
lastWindowHeight = $(window).height();
$('#destino_1').html(cont++);
}
サイズ変更イベントが要素によって発生したか、実際にウィンドウのサイズを変更したかを調べる方法は次のとおりです。
イベントのtarget.nodeTypeが存在しない場合、ページ上の他の要素にはnodeTypeがあるため、ウィンドウである可能性が高くなります。
そこで、チェックを追加した擬似コード(jQueryを使用)です。
$(window).resize(function(event){
if ( $(event.target.nodeType).length == 0 ){
// Anything here is run when the window was resized
// not executed when an element triggered the resize
}
});
(function ($){
//if ie8 -> return;
var lastHeight = 0;
var lastWidth = 0;
$(window).resize(function(event){
if (window.innerHeight == lastHeight && window.innerWidth == lastWidth)
{ event.stopImmediatePropagation(); }
lastHeight = window.innerHeight;
lastHeight = window.innerWidth;
});
})();
私のためにトリックをします...