JS runs before CSS

This is currently happening in chrome, in firefox I did not have this problem (yet).

Here is a VERY simplified version of my problem.

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(); }); 

Problem:

So what does it give when I resize (without drag and drop)? Well, javascript starts first and sets the position to <a></a> , then CSS applies a change in height if we are <992 px.

Logically, the button is now visually located outside the div, and not on the border, as I originally defined it.

Workaround proposed in this post.

jQuery - how to wait for the "end" of the "resize" event and only then perform an action?

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

Workaround is not what I'm looking for:

However, in my situation, I really don’t only need to call “resize” when resizing is actually done. I just want my javascript to start after css has finished loading / or finished with this change. And it's just really slow, using this function to “randomly” run JS when css can be completed.

Question:

Is there a solution? Does anyone know of a method in js to wait for css to fully make changes while resizing?

Additional Information:

Testing this with jsfiddle will most likely not give you the same result as I. My css file has many lines and I use Twitter Bootstrap. These two take up a lot of resources, slowing down the css application (I think, tell me if I am wrong).

Miljan Puzović - proposed a solution by uploading css files via js, and then applied js changes when the js event on css ends.

+6
source share
7 answers

I think that these simple three steps will achieve the intended behavior (please read carefully: I also suggest reading more about the attributes mentioned to deeply understand how this works):

  • Responsive and fluid layouts should always be primarily (if not violin) resolved using CSS .

    So, remove all your JavaScript code.

  • You have fully placed the inner element a#clickMe .

    This means that it will be located within its closest relative to the located element. According to the provided style, it will be placed in the body element, since in any other element there is no position: relative; (the default value of position is static ). Given a script, it seems that it should be placed in its direct parent container. To do this, add position: relative; into the div.thumbnail element.

  • In the script you specified, it seems that you need to place a#clickMe at the bottom of the div.thumbnail .

    Now that we are sure that the styles added to a#clickMe refer to div.thumbnail , just add bottom: 0px; in the element a#clickMe , and it will be placed accordingly regardless of the height that its parent has. Note that this will automatically change when the window is resized (without the need for a script).

The final code will be like this ( see fiddle here ):

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; } } 

If you still insist on detecting changes to your media request, see the following links:

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 - How to Determine When Media Requests Start

Bootstrap: Reactive Design - Running JS when resizing a window from 980px to 979px

+5
source

I like your workaround (I used to do this for a similar problem, I don’t think that half a second is too long for the user to wait, but maybe this is for your needs ...).

Here is an alternative that you most likely thought of, but I don’t see it being mentioned here. Why not do it all through javascript and remove your @media (max-width.... from your 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() }); } 
+4
source

On the html page, put the link in the css file in the head section; then put a link to the js file immediately before the / body tag and see what happens. This way css will load always up to js. Hope this helps you.

+2
source

Have you tried to bind the resizing handler not to the window, but to the object you want to listen to for resizing?

Instead

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

You can try

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

Or maybe,

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

I agree with falsarella that you should try to use only CSS to do what you are trying to do.

In any case, if you want to do something with JS after applying CSS, I think you can use requestAnimationFrame , but I could have experienced it myself because I could not reproduce the behavior that you are explaining.

From the MDN document:

window.requestAnimationFrame () tells the browser that you want to perform the animation and request that the browser invoke the specified function to update the animation before the next redraw . The method takes as an argument a callback to call before repainting.

I would try something like this:

 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); 
+1
source

Does anyone know of a wait method before css is fully loaded?

how about $(window).load(function() { /* ... */ } ? (it only performs this function when the page is fully loaded, so after loading css)

-1
source

Source: https://habr.com/ru/post/970733/


All Articles