Global Javascript not working

On my website, https://klimatriksdagen.se, I have previously used a lot of references to functions in the Global JS (available via Theme Options -> JS) from various individual pages. It has always worked. The “old” links to global JS functions still do, but when trying to link new pages to old global JS or linking to new global JS functions from old pages, neither works. I get error messages like (index):727 Uncaught ReferenceError: testfn is not defined at (index):727.

I don’t know what has caused this. It is not a jQuery issue, although I use it a lot (the testfn() referenced to above is a vanilla JS fn).

I recently migrated the site to https. Can that be the cause, and if so what do I do to fix it?

Hi Kalle,

Thank you for writing in, but regretfully we can not provide support for 3rd party scripts. What we can only advise is please do testing for a plugin conflict. You can do this by deactivating all third party plugins, and seeing if the problem remains. If it’s fixed, you’ll know a plugin caused the problem, and you can narrow down which one by reactivating them one at a time.

I’m seeing a different JS error on your homepage it’s Uncaught RangeError: Maximum call stack size exceeded. Please see the search results related to that error.

Thank you for understanding,

Hi,

Maybe you misunderstood my post. The scripts are not third-party – I have written them myself, or in some rare cases, they have been adopted from code you at themeco/apex have devised. Anyway, the code itself is not the problem since the same code works on some pages and not on others: specifically, global js code referenced to from pages created earlier still gets called ok, while references to the same code from recently created pages give the ReferenceError cited previously.

Since I access the global js through the X Theme Options, I assumed that you would be able to address problems associated with referencing to that js.

Hello Kalle,

Thanks for updating in! I have checked your site and it appears that you have several lines of JS code. I would recommend that you use JS lint to check for your codes.

Both of the site should be able to help you in checking your code. By the way, I would recommend that you temporarily remove your code and test your site. If the error disappears then most probably, the error is coming from your code.

Please let us know how it goes.

Hi again,

Please understand that my problem is not errors in the javascript code. Each piece of code is ok syntactically (the Maximum call stack size exceeded errors have appeared regularly before and do not seem to have caused any malfunction of the site).

The problem is that the code in my Global JS can no longer be found by new JS calls from individual pages. Old calls still work. If I copy and paste the code from the Global JS to the JS for an individual page, then the code works. It is the referencing from the page to the Global JS that no longer can be established.

Example:

The “old” page https://klimatriksdagen.se/om has since a long time had a JS call to the Global JS functions engelska() and svenska() (these are used to switch between English and Swedish versions of the page content). These calls still work.

However, if I create a new page and include a call to one of these global functions in that page’s JS, I get an Uncaught ReferenceError.

Also, if I create a new function in the Global JS and try to call that function from an “old” page such as the one mentioned above, the same error occurs.

To state my problem once again: it is not the JS code that fails, it is the linkage from individual pages to the Global JS that is the problem.

Hello kalle,

Maximum call stack size exceeded is a JS error coming from your code. This is not related to the theme or the page whatsoever. You might want to check out this links and refer to them how to troubleshoot your issue:

Hope this helps.

No, sorry, it does not help. The Maximum call stack size exceeded error is completely unrelated to the issue for which I am trying to get your help. I have now located the cause of that error and corrected it. Thus, my page’s JS no longer causes the Maximum call stack size exceeded error but the actual problem I have tried to raise here still persists.

Please find a demo demonstrating that problem on this page: https://klimatriksdagen.se/error-demo/

Here are the first lines of my Global JS code as retrieved from the X Theme Options page:

And here is the JS code for the page https://klimatriksdagen.se/error-demo/:

And here is the resulting error message:

The code line referenced in the error message looks like this:
<script id="cornerstone-custom-content-js" type="text/javascript">testfn();</script>

The global JS code appears immediately below this offending line, so there does not seem to be a problem with locating the global JS code as I originally thought.

Now could you please help me with the actual issue I was asking you about all along: why do I get the Uncaught ReferenceError: testfn is not defined error, and what do I do about it??

Hello Kalle,

Thanks for the update.

Please be informed that when you add a custom JS code into the section, you will need to wrap your code with the jQuery function. For example;

(function($){
  function testfn(){
    alert("test");
  }

  $(window).on('load', function(){
    testfn();
  });
})(jQuery);

Hope this explains it briefly.

It is actually the other way around. If I put testfn() outside of the jQuery(function($){}); enclosure, it is actually executed, if the call is put within such an enclosure …

However, no function within the jQuery wrap in the Global JS is recognised on the page https://klimatriksdagen.se/error-demo/ . Please go there and see for yourself. The page’s JS is displayed in the content. #testing refers to the gray code text area. If you click that, the page will try and call testfn() . And it will fail.

jQuery(function($){ $(document).ready(function(){ $("#testing").click(function(){ testfn(); }); }); });

The Global JS is now completely wrapped in jQuery, including testfn() . I still get the Uncaught ReferenceError .

And btw, the jQuery load() method used in your suggestion is long deprecated and removed from v 3+.

Hello Kalle,

Thanks for updating in!

The ‘whatever’ function is inside a different scope. In JavaScript a function defines the scope of the code it contains, so if you want to share it you need to define it in a location that your other code can see.

You also don’t need to define functions inside the document ready function, you could just define outside of the ready() callback. Eg:

// Your function call from another file or Cornerstone's custom JS section
(function($){
    $(document).ready(function(){
        $('button').click(function(){
            whatever();
        });
    });
})(jQuery);


// This script loads from another external file or from the Global JS
(function($){
    
    function whatever()
    {
         alert('yes');
    }
    
    $(document).ready(function(){
        // run something else
    });
})(jQuery);

In your code here:

by defining the testfn() inside the callback of ‘.ready()’, you’d have a chicken and egg thing going, you could never be sure the function would be defined when you actually want to use it, so try defining your functions first outside of ‘.ready()’.

By the way, I wasn’t using the load() function. I was actually using the .on() function.

Hope this helps,

Hi,

Thanks for the reply. I get the chicken and egg argument, and I have always kept my non-anonymous jQuery functions outside the ready() wrap before. I was just playing stupid for a brief time :slight_smile: Those functions are now back outside of ready().

However, my problem doesn’t seem to be related to that either.

In fact, I now realise that none of my global JS functions can be called from pages. Please disregard any claims to the contrary above.

Is the Global JS even intended to contain functions that should be accessible to calls from any page? That was my presumption, but maybe I have been wrong all the time?

If I enter the code alert("test") in my global JS (inside ready()), that code is executed every time a page loads. But when I include testfn(){alert("test");} in the global JS (outside ready()), it can’t be called from the content JS of any page. Is this maybe how it is suposed to work? Please advise me.

Hi Kalle,

Please note that a global JS feature of the theme has nothing to do with any script that added to it. It’s simply a shortcut of placing the JS code within the header or footer. And the jQuery is not native to X theme but to Wordpress. Hence, there should be no issues with old and new sites with the same code.

And yes, it’s added outside ready(), but it still within jQuery( function($) {} ); which has the same scope.

Any function added to any existing function will become local function, and it’s only callable within the function. That’s why it’s not working.

To explain it further, this is wrong


jQuery( function( $ ) { /* code block 1 */
   
  function testfn(){
       alert("test");
     }

});


 jQuery(function($){ /* code block 2 */

  $(document).ready(function(){
   $("body").on("click","#testbtn",function(){
      testfn();      
    });
  });

} );

The correct one is this, making them on the same code block

jQuery( function( $ ) { /* code block 1 */
   
  function testfn(){
       alert("test");
     }

  $(document).ready(function(){
   $("body").on("click","#testbtn",function(){
      testfn();      
    });
  });

} );

My question is, why are you separating them? And if you’re planning on separating them then I recommend making your function part of the jQuery. It’s been like that and it’s not theme or Wordpress limitation. If it’s just plain javascript, then there should be no problem since it’s not wrapped within jQuery function.

Thanks!

My mistake was that since it is called Global JS then I thought the scope of the code (including the functions) would be, well, global.

My original idea was that I might want function F to be triggered by event E1 on page P1 whereas the same function would be triggered by another event E2 on page P2. If the functions in Global JS had indeed been global in scope, then I could have attached different event listeners on page P1 and P2 but they would both have called global function F.

That does not seem to be possible.

Hello Kalle,

Regretfully what you have in mind is not possible. You may need to look for other alternatives instead.

Best Regards.

Yes. The solution I have resorted to instead is to also put the event listeners that are using common functions into the global JS code. That way I don’t have to use several copies of the same function on different pages.

Great! Thanks for letting us know that you have figured out a way to get what you have in mind.

Hi,

I feel this thread is very confusing to read for an outsider, and since my question was built on a misunderstanding, and since a lot of your replies do not answer my actual questions, it might be better to erase it. One could replace it with a post stating that the Global JS does not have global scope with respect to variable and function names in the content JSs. What do you say?

Hi Kalle,

I’d like to add more clarification :slight_smile:

The scope depends on how and where it’s declared, so we can’t really say it doesn’t have or have a global scope. It depends on the user who is adding the code. But the term global that is related the theme only means add to ALL pages in contrast to cornerstone CSS which is LOCAL to specific page. It’s completely unrelated to javascript scope which completely depends on how user coded it.

From previous reply, I only provided one possible solution but there are others too. Example,

As this works as my previous recommendation,

jQuery( function( $ ) { /* code block 1 */
   
  function testfn(){
       alert("test");
     }

  $(document).ready(function(){
   $("body").on("click","#testbtn",function(){
      testfn();      
    });
  });

} );

This also works,

   
function testfn(){

jQuery( function( $ ) { /* code block 1 */

       alert("test");

});
 
}



 jQuery(function($){ /* code block 2 */

  $(document).ready(function(){
   $("body").on("click","#testbtn",function(){
      testfn();      
    });
  });

} );

That’s because testfn() became global (not Theme’s term global, but javascript scope). How do we know which is global and local? This code should explain it

<script>

/* anything place here is global, variable or function */
var global_width = 100;

function lets_multiply () {  /* this is the same as jQuery ( function() {} ); */

	/* anything here is local to lets_multiply () */
	var local_width = 100;

	alert ( global_width * local_width );

	function say_hello() {

		alert('HELLO');

	}

}

/* anything place here is global, variable or function */

function lets_divide() {  /* this is the same as jQuery ( function() {} ); */
	
	alert ( global_width / local_width );

	say_hello();

}

/* anything place here is global, variable or function */

</script>

If you call lets_multiply(), it works without an issue. But try calling lets_divide(), it will have error since local_width is not defined globally, nor say_hello(). They belong to lets_mulitply(), and even if you call them anywhere on other pages, it will not work since they are locally declared within existing function.

Again, all of this is not related Theme’s global javascript placement, it’s just a term for making the added script available for all pages, it doesn’t have capability to compile the script to decide which is global, it’s still the browser that executes it.

Thanks!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.