1

I have a simple javascript/jquery task which runs on page load.

Nothing changes on the page when I click refresh - I'm just giving it some reasonable testing - however I noticed that sometimes one of the functions doesn't complete correctly.

Here are the functions:

$(document).ready(function () {
    initialise();
    load();
});

// 1. Cache the main selectors just in case the window is resized
function initialise() {
    $banners = $("#header .banner");
}

// 2. Loop through each of the elements
function load() {
    $banners.each(function () {
        setBannerStyle($(this));
    });
}

// 3. Add attributes to each of the banner elements
function setBannerStyle($selector) {

    icon = $selector.find(".icon").first().length;
    rows = getRows($selector.find(".message").first());

    $selector.attr({
        "data-icon": icon,
        "data-rows": rows
    });
}

// 4. Helper to do the workings out
function getRows($selector) {

    var height = $selector.height();
    var lineHeight = parseFloat($selector.css("line-height"));
    var rows = Math.round(height / lineHeight);

    return rows > 2 ? 2 : rows;
}

As you can see there is no complexity and the number of elements to loop through is rarely more than one.

However, on rare occasions the number of rows returns NAN. How can I ensure that a valid number is always returns (or at least improve the chance of it not happening). It currently fails about once in 10 on my quad core i5 processor.

To be clear, I don't wan't to set defaults when it fails - I want to try and stop it failing in the first place.

Any advice appreciated as I'm not too great with javascript.

John Ohara
  • 2,821
  • 3
  • 28
  • 54
  • when `getRows()` is called -- has the DOM successfully loaded #header .banner .message ? (my guess is that the DOM element didn't render in time for when the JS executed) – Doug Jun 05 '18 at 14:25
  • If you are getting NAN for number of rows that means either height or lineHeight in null. – Rajesh Kumar Jun 05 '18 at 14:25
  • You may want to take a look at this: https://stackoverflow.com/questions/3698200/window-onload-vs-document-ready – git-e-up Jun 05 '18 at 14:26
  • @git-e-up - from what I can see, document ready waits for html - and the thing that I'm measuring is values inside html elements - so should be okay. – John Ohara Jun 05 '18 at 14:33
  • @doug - I thought document ready was to ensure the html was ready. – John Ohara Jun 05 '18 at 14:34
  • @JohnOhara I'm not an expert, but I think that while the DOM may be loaded, not all images necessarily have. So if you're trying to get the height of a banner, it may not be available at the time of `$(document).ready` – git-e-up Jun 05 '18 at 14:39
  • @git-e-up - the container only contains text. – John Ohara Jun 05 '18 at 14:40
  • @RajeshKumar - it is indeed line-height but I need to know how I can make it more robust. – John Ohara Jun 05 '18 at 14:42

2 Answers2

0

Try using .outerHeight() instead of .height() when getting var height

Also, ensure that the line-height variable is set on the $selector element before attempting to parse it, and the $selector variable is also not undefined.

If any of those variables aren't set for any reason, you'll get a NaN result.

You can console.log(variable) all of these to find out what's going on and see the variable states when something doesn't work.

This sounds like it could be a race condition, so if the above suggestions don't work, try using setTimeout(function, interval) to delay the execution of those functions.

Will Jones
  • 1,861
  • 13
  • 24
0

I found this code which seems to work a treat - replaced document.ready() and hammered it hundreds of times a minutes without fail.

let stateCheck = setInterval(() => {
  if (document.readyState === 'complete') {
    clearInterval(stateCheck);
    // document ready
  }
}, 100);

Credit goes to : this site

John Ohara
  • 2,821
  • 3
  • 28
  • 54