Comment puis-je me connecter à un événement de redimensionnement de la fenêtre du navigateur?
Il existe un moyen jQuery d'écouter les événements de redimensionnement mais je préférerais ne pas l'intégrer dans mon projet pour cette seule exigence.
Comment puis-je me connecter à un événement de redimensionnement de la fenêtre du navigateur?
Il existe un moyen jQuery d'écouter les événements de redimensionnement mais je préférerais ne pas l'intégrer dans mon projet pour cette seule exigence.
Réponses:
jQuery enveloppe simplement l' resize
événement DOM standard , par exemple.
window.onresize = function(event) {
...
};
jQuery peut faire un certain travail pour s'assurer que l'événement de redimensionnement est déclenché de manière cohérente dans tous les navigateurs, mais je ne suis pas sûr si l'un des navigateurs diffère, mais je vous encourage à tester dans Firefox, Safari et IE.
window.addEventListener('resize', function(){}, true);
window.onresize = () => { /* code */ };
ou mieux:window.addEventListener('resize', () => { /* code */ });
Tout d'abord, je sais que la addEventListener
méthode a été mentionnée dans les commentaires ci-dessus, mais je n'ai vu aucun code. Puisque c'est l'approche préférée, la voici:
window.addEventListener('resize', function(event){
// do stuff here
});
removeEventListener
.
Ne remplacez jamais la fonction window.onresize.
Au lieu de cela, créez une fonction pour ajouter un écouteur d'événements à l'objet ou à l'élément. Cela vérifie et empêche les écouteurs de fonctionner, puis remplace la fonction de l'objet en dernier recours. Il s'agit de la méthode préférée utilisée dans les bibliothèques telles que jQuery.
object
: l'élément ou l'objet fenêtre
type
: redimensionner, faire défiler (type d'événement)
callback
: la référence de la fonction
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;
}
};
Ensuite, l'utilisation est comme ceci:
addEvent(window, "resize", function_reference);
ou avec une fonction anonyme:
addEvent(window, "resize", function(event) {
console.log('resized');
});
attachEvent
n'est plus pris en charge. La voie privilégiée pour l'avenir est addEventListener
.
elem == undefined
. Il est possible (bien que peu probable) que "non défini" soit défini localement comme autre chose. stackoverflow.com/questions/8175673/…
L'événement de redimensionnement ne doit jamais être utilisé directement car il est déclenché en continu pendant que nous redimensionnons.
Utilisez une fonction anti-rebond pour atténuer les appels en excès.
window.addEventListener('resize',debounce(handler, delay, immediate),false);
Voici un rebounce commun flottant autour du net, mais recherchez des plus avancés comme featuerd dans 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);
};
};
Cela peut être utilisé comme ça ...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
Il ne se déclenchera jamais plus d'une fois tous les 200 ms.
Pour les changements d'orientation mobile, utilisez:
window.addEventListener('orientationchange', () => console.log('hello'), false);
Voici une petite bibliothèque que j'ai constituée pour prendre soin de cela proprement.
(...arguments) => {...}
(ou ...args
pour moins de confusion) car la arguments
variable n'est plus disponible dans sa portée.
Solution pour 2018+:
Vous devez utiliser ResizeObserver . Il s'agit d'une solution native du navigateur qui a de bien meilleures performances que d'utiliser l' resize
événement. De plus, il supporte non seulement l'événement sur le document
mais aussi sur l'arbitraire 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);
Actuellement, Firefox, Chrome et Safari le prennent en charge . Pour les autres navigateurs (et les anciens), vous devez utiliser un polyfill .
Je crois que la réponse correcte a déjà été fournie par @Alex V, mais la réponse nécessite une certaine modernisation car elle a plus de cinq ans maintenant.
Il y a deux problèmes principaux:
Ne jamais utiliser object
comme nom de paramètre. C'est un mot réservé. Cela étant dit, la fonction fournie par @Alex V ne fonctionnera pas strict mode
.
La addEvent
fonction fournie par @Alex V ne renvoie pas le event object
si la addEventListener
méthode est utilisée. Un autre paramètre doit être ajouté à la addEvent
fonction pour permettre cela.
REMARQUE: le nouveau paramètre to addEvent
a été rendu facultatif afin que la migration vers cette nouvelle version de fonction n'interrompe aucun appel précédent à cette fonction. Toutes les utilisations héritées seront prises en charge.
Voici la addEvent
fonction mise à jour avec ces modifications:
/*
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;
};
Un exemple d'appel à la nouvelle addEvent
fonction:
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);
Merci d'avoir référencé mon article de blog sur http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html .
Bien que vous puissiez simplement vous connecter à l'événement de redimensionnement de fenêtre standard, vous constaterez que dans IE, l'événement est déclenché une fois pour chaque mouvement X et une fois pour chaque mouvement de l'axe Y, ce qui entraîne le déclenchement d'une tonne d'événements pouvant avoir des performances impact sur votre site si le rendu est une tâche intensive.
Ma méthode implique un court délai d'attente qui est annulé lors d'événements ultérieurs afin que l'événement ne se propage pas à votre code jusqu'à ce que l'utilisateur ait fini de redimensionner la fenêtre.
window.onresize = function() {
// your code
};
Le billet de blog suivant peut vous être utile: Correction de l'événement de redimensionnement de la fenêtre dans IE
Il fournit ce code:
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); }
Les solutions déjà mentionnées ci-dessus fonctionneront si tout ce que vous voulez faire est de redimensionner la fenêtre et la fenêtre uniquement. Toutefois, si vous souhaitez que le redimensionnement soit propagé aux éléments enfants, vous devrez propager l'événement vous-même. Voici un exemple de code pour le faire:
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);
});
Notez qu'un élément enfant peut appeler
event.preventDefault();
sur l'objet événement transmis comme premier Arg de l'événement resize. Par exemple:
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_];
}
}
}