Como conectar em um evento de redimensionamento da janela do navegador?
Existe uma maneira do jQuery de ouvir eventos de redimensionamento, mas eu preferiria não incluí-lo no meu projeto apenas para esse requisito.
Como conectar em um evento de redimensionamento da janela do navegador?
Existe uma maneira do jQuery de ouvir eventos de redimensionamento, mas eu preferiria não incluí-lo no meu projeto apenas para esse requisito.
Respostas:
O jQuery está apenas envolvendo o resize
evento DOM padrão , por exemplo.
window.onresize = function(event) {
...
};
O jQuery pode fazer algum trabalho para garantir que o evento de redimensionamento seja acionado de forma consistente em todos os navegadores, mas não tenho certeza se algum dos navegadores difere, mas recomendamos que você teste no Firefox, Safari e IE.
window.addEventListener('resize', function(){}, true);
window.onresize = () => { /* code */ };
or better:window.addEventListener('resize', () => { /* code */ });
Primeiro, sei que o addEventListener
método foi mencionado nos comentários acima, mas não vi nenhum código. Como é a abordagem preferida, aqui está:
window.addEventListener('resize', function(event){
// do stuff here
});
removeEventListener
.
Nunca substitua a função window.onresize.
Em vez disso, crie uma função para adicionar um Event Listener ao objeto ou elemento. Isso verifica e encerra os ouvintes não funcionarem, e substitui a função do objeto como último recurso. Este é o método preferido usado em bibliotecas como o jQuery.
object
: o elemento ou objeto da janela
type
: redimensionar, rolar (tipo de evento)
callback
: a referência da função
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;
}
};
Então use é assim:
addEvent(window, "resize", function_reference);
ou com uma função anônima:
addEvent(window, "resize", function(event) {
console.log('resized');
});
attachEvent
não é mais suportado. A maneira preferida para o futuro é addEventListener
.
elem == undefined
. É possível (embora improvável) que "indefinido" seja definido localmente como outra coisa. stackoverflow.com/questions/8175673/…
O evento de redimensionamento nunca deve ser usado diretamente, pois é disparado continuamente à medida que redimensionamos.
Use uma função de rejeição para atenuar o excesso de chamadas.
window.addEventListener('resize',debounce(handler, delay, immediate),false);
Aqui está um debounce comum flutuando pela rede, embora procure por outros mais avançados como feitos em 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);
};
};
Isso pode ser usado assim ...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
Ele nunca dispara mais de uma vez a cada 200ms.
Para alterações na orientação móvel, use:
window.addEventListener('orientationchange', () => console.log('hello'), false);
Aqui está uma pequena biblioteca que eu montei para cuidar disso ordenadamente.
(...arguments) => {...}
(ou ...args
para menos confusão), pois a arguments
variável não está mais disponível em seu escopo.
Solução para 2018+:
Você deve usar ResizeObserver . É uma solução nativa do navegador que tem um desempenho muito melhor do que usar o resize
evento. Além disso, ele não apenas suporta o evento no, document
mas também no arbitrário 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);
Atualmente, o Firefox, Chrome e Safari suportam . Para outros navegadores (e mais antigos), é necessário usar um polyfill .
Acredito que a resposta correta já tenha sido fornecida pelo @Alex V, mas a resposta exige alguma modernização, pois ela tem mais de cinco anos.
Existem dois problemas principais:
Nunca use object
como um nome de parâmetro. É uma palavra reservered. Com isso dito, a função fornecida do @Alex V não funcionará strict mode
.
A addEvent
função fornecida pelo @Alex V não retorna event object
se o addEventListener
método for usado. Outro parâmetro deve ser adicionado à addEvent
função para permitir isso.
NOTA: O novo parâmetro para addEvent
foi tornado opcional para que a migração para esta nova versão da função não interrompa nenhuma chamada anterior para esta função. Todos os usos herdados serão suportados.
Aqui está a addEvent
função atualizada com estas alterações:
/*
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;
};
Um exemplo de chamada para a nova addEvent
função:
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);
Obrigado por consultar a postagem do meu blog em http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html .
Enquanto você pode simplesmente conectar-se ao evento de redimensionamento de janela padrão, verá que, no IE, o evento é disparado uma vez para cada movimento do eixo X e uma vez para cada eixo Y, resultando em uma tonelada de eventos sendo disparados que podem ter um desempenho impacto no seu site se a renderização for uma tarefa intensiva.
Meu método envolve um curto tempo limite que é cancelado em eventos subseqüentes, para que o evento não chegue ao seu código até que o usuário termine de redimensionar a janela.
window.onresize = function() {
// your code
};
A seguinte postagem no blog pode ser útil para você: Corrigindo o evento de redimensionamento de janela no IE
Ele fornece este código:
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); }
As soluções já mencionadas acima funcionarão se tudo que você quiser fazer é redimensionar a janela e apenas a janela. No entanto, se você deseja que o redimensionamento seja propagado para elementos filho, será necessário propagar o evento você mesmo. Aqui está um exemplo de código para fazer isso:
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);
});
Observe que um elemento filho pode chamar
event.preventDefault();
no objeto de evento que é passado como o primeiro Arg do evento de redimensionamento. Por exemplo:
var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
...
event.preventDefault();
});
<script language="javascript">
window.onresize = function() {
document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
}
</script>
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_];
}
}
}