1

I have some javascript that was written years back. I've just noticed it's throwing up errors in the console on every page the object isn't included on. I get errors like...

Cannot read property 'top' of undefined TypeError: Cannot read property 'top' of undefined

and

Uncaught TypeError: Cannot read property 'top' of undefined at placeLines (main.js:276) at HTMLDocument. (main.js:299) at j (jquery-3.1.1.min.js:2) at k (jquery-3.1.1.min.js:2)

The javascript I'm running is as follows:

$(function(){
    placeLines = function(){

        for(i=0; i<=9; i++){
            var Dy = $('.ball-container'+i).position().top - $('.ball-container'+(i+1)).position().top;
            var Dx = $('.ball-container'+(i+1)).position().left - $('.ball-container'+i).position().left;
            var length = Math.sqrt(Dy*Dy + Dx*Dx);
            var angle = Math.atan2(Dy, Dx) * (-1);
            var containerHeight = $('#animated-line > .inner').height();
            var transform = 'rotate('+angle + 'rad)';
            $('.line'+i).css({
                'transform': transform
            })

            var offsetTop = $('.ball-container'+i).offset().top +6;
            var offsetLeft= $('.ball-container'+i).offset().left +6;

            $('.line-box'+i).css({
                'width': length +'px'
                }).offset({
                left: offsetLeft,
                top: offsetTop
            });
        }
    };

    $(document).ready(function(){
        placeLines();
    });

    $(window).resize(function(){
        console.log('resizing');
        placeLines();
    });
});

How can I stop these errors, can I check if the object is on the page before running the script or something like that? The parent/containing div is animated-line.

Thanks in advance.

user1406440
  • 1,329
  • 2
  • 24
  • 59
  • _"I've just noticed it's throwing up errors in the console on every page it's not included on."_ If it's _not_ included on the page how can it be throwing up errors? – Andy Sep 28 '17 at 15:22
  • On every page the object isn't included on, in the HTML. So the script runs and looks for something that isn't there. As it's a generic JS file, included on every page. – user1406440 Sep 28 '17 at 15:23
  • Ah, the _object_, not the script. Thanks for clearing that up. – Andy Sep 28 '17 at 15:24
  • Well, you could check `$('#animated-line').length` and if it's `0` don't run the script. – Andy Sep 28 '17 at 15:25
  • Yeah sorry, I tied myself in knots writing that! – user1406440 Sep 28 '17 at 15:29

2 Answers2

2

edit: I didn't realize you meant you wanted to check if the object existed on the page. I would recommend the check that Andy mentioned in a comment on your post.

if($('#animated-line').length > 0) could go as the first line in your placeLines() function. Then it will only actually execute if the function exists. Or, in your $(document).ready and $(window).resize, you could place the above check; I just try to avoid redundant checks.

Also see: Is there an "exists" function for jQuery?

  • Thanks for the reply. I replaced `$(document).ready(function(){` with `$('#animated-line').load(function(){` but then in the console I get a new error of `a.indexOf is not a function at r.fn.init.r.fn.load` – user1406440 Sep 28 '17 at 15:32
  • updated, sorry i had also been confused - thought the issue was code executing before the object loaded, not that the object was not present on some pages. – Charlie Unfricht Sep 28 '17 at 15:35
  • Yeah my bad on that. I've tried those methods and they both work, thanks! What would be best? I'm thinking wrapping both of them could be best as they're never needed separately? – user1406440 Sep 28 '17 at 15:43
  • 1
    I think in this case it makes more sense to wrap both, since that way you're not calling the function on every page (even if it doesn't do anything), but only on the pages with the objects the function acts on. But I also think it's more a matter of personal preference :) – Charlie Unfricht Sep 28 '17 at 15:46
1

Assuming that either all ball containers exist or none, change

$(document).ready(function(){
    placeLines();
});

$(window).resize(function(){
    console.log('resizing');
    placeLines();
});

to

if ($('.ball-container0').length){ // check if ball containers exist and only then use the placeLines method

    $(document).ready(function(){
        placeLines();
    });

    $(window).resize(function(){
        console.log('resizing');
        placeLines();
    });
}
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317