JS lance avant CSS

Cela se produit actuellement dans Chrome, dans Firefox je n'ai pas eu ce problème (pour le moment).

Voici une version très simplifiée de mon problème.

HTML:

<div class="thumbnail"> <a href='#' id="clickMe">Click me!</a> </div> 

CSS:

 div { width: 200px; height: 300px; background-color: purple; } a { position: absolute; } @media (max-width: 991px) { div { height: 200px; } } 

Javascript:

 $(document).ready(function () { var $parent = $('#clickMe').parent(); function resize() { $('#clickMe').offset({ top: $parent.offset().top + $parent.height()-$('#clickMe').height() }); } $(window).on('resize', resize); resize(); }); 

Le problème:

Alors, qu'est-ce que cela donne quand je redimensionner (sans traîner)? Bien javascript lance en premier et définit la position du <a></a> , alors CSS applique le changement de hauteur si nous sommes <992 px.

Logiquement, le bouton est maintenant visuellement à l'extérieur de la div et pas sur la bordure comme je l'avais défini à l'origine.

Solution temporaire proposée dans cette publication.

JQuery – comment attendre l'événement 'fin' de 'redimensionner' et seulement alors effectuer une action?

 var doit; $(window).on('resize', function(){ clearTimeout(doit); doit = setTimeout(resize, 500); }); 

La solution temporaire n'est pas ce que je recherche:

Cependant, dans ma situation, je n'ai pas vraiment besoin d'appeler «redimensionner» lorsque l'événement de redimensionnement est réellement effectué. Je veux juste que mon javascript s'exécute après que le css ait fini de charger / ou fini avec ses modifications. Et il se sent simplement super lent en utilisant cette fonction pour exécuter «JAIEMENT» le JS lorsque le css pourrait être terminé.

La question:

Y a-t-il une solution à cela? Quelqu'un connait-il une technique dans js pour attendre que css soit complètement terminé en appliquant les modifications lors d'un redimensionnement?

Information additionnelle:

Tester cela dans jsfiddle ne vous donnera probablement pas le même résultat que I. Mon fichier css a plusieurs lignes, et je suis en utilisant Twitter Bootstrap. Ces deux occupent beaucoup de ressources, ralentissant l'application css (je pense, dites-moi si je me trompe).

Miljan Puzović – a proposé une solution en chargeant les fichiers css via js, puis appliquez js changements lorsque l'événement js sur css se termine.

Je pense que ces trois étapes simples atteindront le comportement prévu (lisez-le attentivement: je suggère également de lire plus sur les attributs mentionnés pour bien comprendre comment cela fonctionne):

  1. Les problèmes de mise en page réactifs et fluides devraient toujours être résolus (si ce n'est pas possible) avec CSS .

    Supprimez donc tout votre code JavaScript .

  2. Vous avez absolument positionné l'élément a#clickMe intérieur.

    Cela signifie qu'il sera positionné dans son élément le plus proche placé. Par le style fourni, il sera positionné dans l'élément du body , car il n'y a pas de position: relative; Dans n'importe quel autre élément (la valeur de position par défaut est static ) . Selon le script fourni, il semble qu'il soit positionné dans son conteneur parent direct. Pour ce faire, ajoutez la position: relative; À l'élément div.thumbnail .

  3. Par le script que vous avez fourni, il semble que vous devez placer a#clickMe au bas de div.thumbnail .

    Maintenant que nous sommes sûrs que les styles ajoutés à a#clickMe sont relatifs à div.thumbnail . Juste ajoute bottom: 0px; a#clickMe élément a#clickMe et il sera positionné en conséquence, indépendamment de la taille de son parent. Notez que cela réorganisera automatiquement lorsque la fenêtre est redimensionnée (sans script requis).

Le code final sera comme ceci ( voir violon ici ):

JS:

  /* No script needed. */ 

CSS:

 div { width: 200px; height: 300px; background-color: purple; position: relative; //added } a { position: absolute; bottom: 0px; //added } @media (max-width: 991px) { div { height: 200px; } } 

Si vous insistez toujours sur la détection de changement de requête médiatique, consultez ces liens:

http://css-tricks.com/media-query-change-detection-in-javascript-through-css-animations/

http://css-tricks.com/enquire-js-media-query-callbacks-in-javascript/

http://tylergaw.com/articles/reacting-to-media-queries-in-javascript

http://davidwalsh.name/device-state-detection-css-media-queries-javascript

Twitter Bootstrap – comment détecter quand les requêtes multimédias commencent

Bootstrap: conception responsable – exécuter JS lorsque la fenêtre est redimensionnée de 980px à 979px

J'aime votre solution temporaire (je l'ai fait pour un problème similaire avant, je ne pense pas qu'une demi-seconde est trop longue pour qu'un utilisateur attend, mais peut-être pour vos besoins …).

Voici une alternative que vous avez probablement pensé, mais je ne le vois pas mentionné, alors voilà. Pourquoi ne pas le faire tout au long de javascript et supprimer votre @media (max-width.... de votre css?

 function resize() { var width = (window.innerWidth > 0) ? window.innerWidth : screen.width; if(width<992){ $("div").each(function(e,obj){$(obj).height(200);}); } $('#clickMe').offset({ top: $parent.offset().top + $parent.height()-$('#clickMe').height() }); } 

Dans la page html, placez le lien vers le fichier css dans la section tête ; Ensuite, mettez le lien dans le fichier js juste avant la balise / body et voyez ce qui se passe. De cette façon, css se chargera toujours avant js. J'espère que cela vous aidera.

Avez-vous essayé de lier le gestionnaire de redimensionnement pas à la fenêtre mais à l'objet que vous souhaitez écouter le redimensionnement?

Au lieu de

 $(window).on('resize', resize); 

Tu peux essayer

 $("#clickMe").on('resize', resize); 

Ou peut-être

 $("#clickMe").parent().on('resize', resize); 
 var didResize = false; $(window).resize(function() { didResize = true; }); setInterval(function() { if (didResize) { didResize = false; console.log('resize'); } }, 250); 

Je suis d'accord avec falsarella que vous devriez essayer d'utiliser uniquement CSS pour faire ce que vous essayez de faire.

Quoi qu'il en soit, si vous voulez faire quelque chose avec JS après l'application du CSS, je pense que vous pouvez utiliser requestAnimationFrame , mais je ne pouvais pas le tester moi-même parce que je n'ai pas pu reproduire le comportement que vous expliquez.

Du document MDN:

La méthode window.requestAnimationFrame () indique au navigateur que vous souhaitez effectuer une animation et demande que le navigateur appelle une fonction spécifiée pour mettre à jour une animation avant le prochain repeint . La méthode prend comme argument un rappel à invoquer avant le repeint.

J'essayerais quelque chose comme ça:

 var $parent = $('#clickMe').parent(); function resize(){ $('#clickMe').offset({ top: $parent.offset().top + $parent.height()-$('#clickMe').height() }); } window.onresize = function(e){ window.requestAnimationFrame(resize); } window.requestAnimationFrame(resize); 

Quelqu'un connait-il une technique pour attendre que css soit complètement terminé?

$(window).load(function() { /* ... */ } il de $(window).load(function() { /* ... */ } ? (Il exécute la fonction uniquement lorsque la page est complètement chargée, donc après la chargement de css)