Освещение событий window.resize в Internet Explorer
Как вам известно, в Internet Explorer событие window.resize запускается, когда изменяется любой элемент на странице. Не имеет значения, изменяется ли элемент страницы путем назначения/изменения его height или style, просто добавив к нему дочерний элемент или что-то еще, даже если изменение размера элемента не влияет на размеры самого окна просмотра.
В моем приложении это вызывает неприятную рекурсию, поскольку в моем обработчике window.resize я изменяю размер <li> элементы, которые, в свою очередь, перегорают window.resize и т.д. Опять же, это только проблема в IE.
Есть ли способ предотвратить window.resize window.resize в IE в ответ на элементы на странице, размер которой изменяется?
Я также должен упомянуть, что я использую jQuery.
Ответы
Ответ 1
Я только что обнаружил еще одну проблему, которая может вам помочь.
Я использую jQuery, и у меня есть событие window.resize для вызова функции, которая будет переставлять div, добавленный в тело.
Теперь, когда я устанавливаю свойство LEFT css этого добавленного div, событие 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;
});
Таким образом, в основном он будет проверять, изменяется ли высота или ширина (что произойдет ТОЛЬКО, когда вы действительно измените размер с помощью окна).
Ответ 2
это имело смысл для меня и, похоже, работает в 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();
}
});
Ответ 3
Свяжите слушателя с изменением размера с помощью .one()
, чтобы он отсоединился после стрельбы. Затем вы можете делать все, что хотите, до тех пор, пока в конце вы переустановите слушателя изменения размера. Я нашел самый простой способ сделать это, поместив прослушиватель resize в анонимную функцию следующим образом:
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()
, но я бросил ее туда как раз в случае и для некоторого дополнительного дросселирования.
Ответ 4
Я решил его, отменив функцию изменения размера, перестроил страницу и снова привязал функцию изменения размера:
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;
Ответ 5
@Ответ 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
});
Ответ 6
Сегодня я столкнулся с этой проблемой и решил включить следующее в мой глобальный файл 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;
});
Для этого требуется прототип.
Ответ 7
Комбинация метода 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 );
Ответ 8
Вы можете попробовать следующее:
Конструктор:
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
Ответ 9
(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;
});
})();
делает трюк для меня...
Ответ 10
<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++);
}
Ответ 11
Вот как я разбираюсь в том, что событие resize было запущено элементом или действительно изменило размер окна:
Если событие 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
}
});
Ответ 12
Я не смог запустить событие изменения размера, когда элемент был изменен (только в IE8).
Однако что такое target
в объекте события, когда вы столкнулись с этой проблемой, не могли бы вы сделать:
$(window).resize(function(e) {
if( e.target != window ) return;
// your stuff here
});
Ответ 13
Мой патч:
<!--[if lte IE 7]>
<script type="text/javascript">
window.onresize = null; // patch to prevent infinite loop in IE6 and IE7
</script>
<![endif]-->
Ответ 14
Это зависит от того, как содержимое находится в событии изменения размера.
Я понял, что приведенное выше решение решается только тогда, когда страница состоит из статического содержимого, а не динамически отображаемых.
В динамическом случае, когда существующее содержимое будет повторно отображаться некоторым событием триггера, например функцией перезагрузки содержимого, нам нужно вместо этого использовать $(document).width() или $(document).height().
Это из-за полосы прокрутки окна.
Если на странице есть полоса прокрутки, и основное содержимое будет перерисовано, нажав кнопку "Обновить", полоса прокрутки исчезнет на событии.
В этом случае $(window).width() или $(window).height() изменяется путем рендеринга содержимого, а не фактическим размером окна.
http://www.tech-step.net/?p=466
Ответ 15
$(window).resize(function(event)
{
if (typeof event.target.tagName == 'undefined')
{
// ...
}
});