JavaScript takes the spotlight before CSS

Currently experiencing this issue in Chrome, although Firefox seems to be working fine so far.

Here is a greatly simplified version of the 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();
});

The issue at hand:

When resizing (without dragging), the JavaScript sets the position of the <a></a> element before the CSS applies any height changes if the window size is less than 992px.

As a result, the button ends up visually outside of the div rather than on the border where it was originally intended to be.

Temporary solution proposed in this post:

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

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

Not satisfied with the temporary solution:

In my case, waiting for the end of the resizing event isn't necessary. I simply want my JavaScript to run after the CSS has finished loading or applying its changes. Using the provided function feels sluggish as it randomly triggers the JS when the CSS may not be fully applied yet.

The question remains:

Is there a way to ensure that JavaScript executes only after CSS has completed making modifications during a resize event? Any techniques in JS to achieve this?

Additional Information:

Please note that testing this on jsfiddle might yield different results due to my extensive CSS file and the utilization of Twitter Bootstrap, both of which can slow down the CSS application process. Your insights are welcome.

Miljan Puzović suggested a solution involving loading CSS files via JS, then triggering JS changes when the CSS event comes to a close.

Answer №1

I believe that following these straightforward three steps will help achieve the desired outcome (make sure to carefully read and understand each step):

  1. For any layout issues related to responsiveness and fluidity, it is best to address them using CSS rather than JavaScript.

    Therefore, eliminate all JavaScript code from your implementation.

  2. The inner element a#clickMe has been positioned absolutely in your script.

    This means it will be positioned relative to its closest element with a position: relative;. Since no other element has this style (by default, they have position: static), it will be positioned within the body element according to the provided style. If you want it to be positioned relative to its parent container, add position: relative; to the div.thumbnail element.

  3. Based on the script you provided, it seems like you want to place a#clickMe at the bottom of div.thumbnail.

    Now that we've established the positioning context for a#clickMe within div.thumbnail, simply add bottom: 0px; to the a#clickMe element to position it accordingly, regardless of its parent's height. This adjustment will automatically adapt when the window is resized without requiring additional scripting.

The revised code snippet looks like this (view 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're still interested in media query change detection, check out these resources:

Link 1

Link 2

Link 3

Link 4

Twitter Bootstrap - how to detect when media queries starts

Bootstrap: Responsitive design - execute JS when window is resized from 980px to 979px

Answer №2

That temporary fix you implemented is quite clever (I've used a similar one in the past for a different issue, personally I don't think half a second is too long of a wait time for users but it might not suit your specific requirements...).

Have you considered another approach that involves handling everything through javascript and removing the @media (max-width.... from your css? It's a possibility worth exploring if you haven't already.

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

}

Answer №3

To enhance the styling of your HTML page, remember to place the link to the CSS file in the head section. Then, make sure to include the link to the JavaScript file right before the closing /body tag. By following this order, the CSS will consistently load before the JS scripts are executed. I trust this tip proves beneficial for you.

Answer №4

Have you attempted binding the resize handler not to the window but to the specific object you want to monitor for resize events?

Instead of

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

You could try

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

Alternatively, you may consider

$("#hoverHere").parent().on('resize', resize);

Answer №5

let isResized = false;
$(window).resize(function() {
    isResized = true;
});
setInterval(function() {
    if (isResized) {
        isResized = false;
        console.log('Window has been resized');
    }
}, 250);

Answer №6

I concur with falsarella's suggestion to utilize CSS for achieving your desired outcome.

However, if you wish to incorporate JavaScript functionality after applying the CSS, you might consider utilizing requestAnimationFrame. Unfortunately, I did not have the opportunity to test this personally as I could not replicate the issue you described.

According to the MDN documentation:

The window.requestAnimationFrame() method informs the browser that you want to execute an animation and requests the browser to call a specified function to update an animation prior to the next repaint. The method requires a callback function argument to be executed before the repaint occurs.

You may want to attempt something along these lines:

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

Answer №7

Does anyone have a solution for delaying the execution of JavaScript until after CSS has finished loading?

Have you considered using

$(window).load(function() { /* ... */ }
? This method ensures that the function is only executed once the entire page, including CSS, has been fully loaded.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can existing servers support server side rendering?

I am currently working on building a Single Page Application (SPA) using the latest Angular framework. The SPA will involve a combination of static HTML pages, server side rendering, and possibly Nunjucks templating engine. My dilemma lies in the fact th ...

Is it possible to implement a jQuery function instead of utilizing an iframe? Iframe tends to have a longer loading time, so using a

Would it be possible to achieve the same functionality as an iframe using the onload function and trigger function in jQuery with a div or anchor tag? I'm looking for alternatives to iframes because they take too long to load. Here is the current cod ...

Hover over elements in jQuery to smoothly transition them from one class to another

Is it possible to achieve this? For example: .class1{ background-image:(whatever.jpg) color: #fff; } .class2{ background-image:(whatever2.jpg) color: #999; } Can I create a fade effect for all elements with class1 to class2 when the mouse hover ...

Prepared SQL Statement in NodeJS for MSSQL using WHERE IN clause

I'm using the sql npm package in my Node.js project. Currently, I have an array of product SKUs like this: var skus = ['product1', 'product2', 'product3']; The SQL query stored in a file looks like this: SELECT * FROM ...

Send data from JavaScript variables to PHP script

I've been trying to figure out how to pass variables from a js function to my database using php, but I've hit a roadblock. Any suggestions on how I can resolve this issue would be greatly appreciated. <html xmlns="http://www.w3.org/1999/xhtm ...

Creating a foolproof image polling platform: A step-by-step guide

I'm in the process of creating a webpage on my site that allows users to view a collection of images. The goal is for each registered user to choose one picture as their favorite, increasing that picture's score by one. The image with the highest ...

Is there a way to automatically click the 'next' arrow on my image slider?

I'm currently working on a website that uses the Semplice theme in Wordpress. The built-in slider doesn't have an autoplay feature, so I attempted to use jQuery to automatically click the 'next' arrow every 5 seconds. However, I ran int ...

What Could Be Causing jQplot to Appear Blank?

As a beginner in jQuery and jQplot, I am facing an issue with plotting an array of points onto a graph in my web application. The graph is just showing up blank and I can't seem to pinpoint where the problem lies... The code responsible for executing ...

Functionality of jQuery Mobile Page

$(document).on("pageshow", "#mappage", function (event) { $("#doldur").append("<li> <label onclick='getBina(" + featuressokak[f].attributes.SOKAKID + ");'>" ...

Issue encountered with the DevExtreme npm module: Uncaught TypeError - $(...).dxButton is not recognized as a function

Instructions for installing DevExtreme npm can be found on their official page here: https://www.npmjs.com/package/devextreme var $ = require('jquery'); require('devextreme/ui/button'); var dialog = require('devextreme/ui/dialog&a ...

Leverage the https module within your React Native application

How can I integrate the https standard library module from Node.js into a React Native project? Specifically, I need to use https.Agent for axios. Is there a recommended approach for achieving this integration? ...

Building an HTML form to generate an array of objects by collecting form data

Hey there, I'm working on an HTML form in React that utilizes form action and FormData. However, when I extract the formData using my method, it shows a structure like this: https://i.stack.imgur.com/nzgLX.png My goal is to have an array of objects ...

What is causing the beforeUpdate hook in Sequelize to fail?

I have a user model with 2 hooks that I am working on. User.beforeCreate(setSaltAndPass) User.beforeUpdate(setSaltAndPass) The first hook works perfectly fine, but the beforeUpdate hook is not triggering as expected. As per the documentation, there should ...

Is there a way to retrieve command line arguments from a running Electron Application?

I am currently facing a challenge with retrieving command line arguments from an Electron application. When the application is launched with command line arguments, I need to utilize these arguments in the renderer process (specifically within a webview). ...

Having trouble with Vue.js implementation of Bootstrap tab navigation?

I am currently working on a vue.js application that consists of 2 routed components. I recently attempted to integrate a bootstrap tab navigation into the first component, but unfortunately, the tab contents are not being properly displayed. <templat ...

The initial menu option stands out due to its unique appearance, created using the :first-child

I am currently designing a website menu and I would like the .current-menu-item - current item, to have a different appearance. However, I want the first item in this menu to have rounded corners (top left, bottom left). How can I achieve this using the :f ...

Has jQuery UI Accordion taken over the design of unordered lists?

I'm having trouble with my website's navigation styling getting messed up by the jQuery accordion. The unordered list inside the .accordion div is overflowing and losing its CSS styling. I've tried adding clearStyle true and autoHeight false ...

What is the most elegant way to retrieve a new item from Firebase and read it?

My goal is to display the result of a successful read on a page, with only one attempt available before the headers are set and the page is sent. I am looking to retrieve one new value, generated after a listener was initiated so as not to pull existing da ...

Instead of displaying the location attribute in an alert, populate it into a text area

I have a function that can retrieve my current location using longitude and latitude coordinates. However, I am looking to automatically fill a text area (Populate Here) with the results instead of displaying an alert. <!DOCTYPE html> <html> ...

I need to use JavaScript to create HTML to PDF and then upload the PDF file to a SharePoint Document Library

Our current project requires us to convert HTML to PDF and save it in a SharePoint Document Library. While we have successfully converted the HTML to PDF using Kendo plugin, we are facing challenges with storing it in SharePoint. It's worth noting th ...