76

I've been sifting around the web trying to find out whats going on here and I have not been able to get a concrete answer.

I have one $(document).ready on my site that seams to run multiple times regardless of the code that is inside it.

I've read up on the bug reports for jQuery about how the .ready event will fire twice if you have an exception that occurs within your statement. However even when I have the following code it still runs twice:

$(document).ready(function() {
    try{    
        console.log('ready');
        }
    catch(e){
        console.log(e);
    }
});

In the console all I see is "ready" logged twice. Is it possible that another .ready with an exception in it would cause an issue? My understanding was that all .ready tags were independent of each other, but I cannot seem to find where this is coming into play?

Here is the head block for the site:

<head>
<title>${path.title}</title>
<meta name="Description" content="${path.description}" />
<link href="${cssHost}${path.pathCss}" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="media/js/fancybox/jquery.fancybox.pack.js" type="text/javascript" ><!-- --></script>
<script src="/media/es/jobsite/js/landing.js" type="text/javascript" ><!-- --></script>
<script src="/media/es/jobsite/js/functions.js" type="text/javascript"><!-- -->    </script>
<script src="/media/es/jobsite/js/jobParsing.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="/media/es/jobsite/js/queryNormilization.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="${jsHost}/js/jquery/jquery.metadata.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="${jsHost}/js/jquery/jquery.form.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="${jsHost}/js/jquery.i18n.properties-min.js" type="text/javascript" charset="utf-8"><!----></script>

<script type="text/javascript" charset="utf-8">

function updateBannerLink() {
    var s4 = location.hash.substring(1);
    $("#banner").attr('href','http://INTELATRACKING.ORG/?a=12240&amp;c=29258&amp;s4='+s4+'&amp;s5=^');
}

</script>
</head>

Pay no attention to the JSP variables, but as you can see i'm only calling the functions.js file once (which is where the .ready function exists)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Xenology
  • 2,357
  • 2
  • 21
  • 39
  • 2
    Is something causing a page refresh or a second page load - some sort of debugging tool like Firebug or something? – Dylan Beattie May 23 '12 at 20:03
  • 1
    It's only logging [once for me](http://jsfiddle.net/HeyJavascript/5Cdh5/). – Elliot Bonneville May 23 '12 at 20:04
  • Can you give any information on the version of jQuery you are using and the browsers that this is happening in? – Victor May 23 '12 at 20:04
  • 1
    I would guess that same code is embedded twice. the DOM ready event gets fired once when the DOM is ready, the ready handler simply binds to that event. if it is binded twice then it will get executed twice. May be you should check for all the javascript to see if this code is repeated somewhere else, or may be you just left a console log in some other handler where some other code is getting executed but you just left a console log. – Alok Swain May 23 '12 at 20:06
  • @ngen - Sure here it is, http://jsfiddle.net/alokswain/xNEtg/.. the reason that happens is because we just listen to the event and can listen multiple times we want, just a simple case of multiple bindings to a single event: the document ready, which fires once. – Alok Swain May 23 '12 at 20:16
  • Its not a case of a console log being left in somewhere, its this specific block that is running twice, I also don't see anywhere that i could be calling a page refresh or a page load. This is happening in all browsers EXCEPT IE – Xenology May 23 '12 at 20:18
  • In my case it happened because of a form element, which used a button for a asynchronous call ... but I forgot to add in the onclick a "return false". (Usually I use jquery only for simple clickdummies) – Brain Jul 02 '19 at 06:10

14 Answers14

71

The ready event cannot fire twice. What is more than likely happening is you have code that is moving or manipulating the element that the code is contained within which causes the browser to re-execute the script block.

This can be avoided by including script tags in the <head> or before the closing </body> tag and not using $('body').wrapInner();. using $('body').html($('body').html().replace(...)); has the same effect.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • I'm not using the .wrapInner() tag at all on my site, and as far as i can tell, i have all script tags contained within the tags of my site, so i don't see how the code could be getting "rerun" ? – Xenology May 23 '12 at 20:16
  • Where is updateBannerLink being called? if it's in an anchor tag, are you preventing the anchor tag from reloading the page? – Kevin B May 23 '12 at 20:18
  • Actually that's a stupid question. Nevermind. If it is happening twice without any interaction from you, the code must be included twice somewhere if the code is in the `` – Kevin B May 23 '12 at 20:19
  • 1
    There are some Javascript libraries (like KendoUI) that will cause the document.ready function to execute multiple times on a single page. It's not impossible. – qJake May 23 '12 at 20:34
  • 12
    The issue here ended up being an IFRAME tag that was included on the page. When removed the document.ready only fired once. As you can see there is an obvious reason as to why the tag is causing a reload on the page – Xenology May 23 '12 at 21:34
  • Ah, so the iframe was including the parent page as it's src, resulting in the script running twice? – Kevin B May 23 '12 at 21:35
  • 1
    Yes, why it wasn't happening in IE i don't know, while this answer was not 100% correct, it lead me to try and find if the page was manipulating the BODY in such a way as to make it load twice, so it set me on the correct path to solving the issue. – Xenology May 29 '12 at 15:42
  • 9
    Avoid using `src="#"` attribute, because it is loading the same page on parent window and inside iframe, that's why it looks like code is called twice. Remove `src` attribute or set it to `"about:blank"` to avoid such behavior. – Inferpse May 07 '13 at 10:14
  • This was a useful answer - I had an element which included a script block which setup an event listener. The container element was being moved in the DOM to somewhere else at DOMReady time, which was binding a second copy of the listener to the event! I wasn't aware that this would happen. – sync Oct 01 '13 at 06:38
  • This was a useful answer for me, I just fixed something that took hours of digging, and turns out that when you use wrapInner() on the $("body") of you page you doc ready will fire twice, causing basically everything jquery does to be double-bound (fun) – Jason FB Jul 18 '14 at 18:59
  • @KevinB _"The ready event cannot fire twice. "_ See http://stackoverflow.com/a/36144130/ – guest271314 May 28 '16 at 18:55
  • @guest271314 It can be executed multiple times, and the callback will run every time, however, the event itself only happens once. It cannot trigger again, causing the callback to happen again, which was the point of this answer. – Kevin B May 28 '16 at 19:05
  • This answer saved me tons of time. I added some initialization code to my JS class so it wont execute the same code twice. Thanks! – leekei Jul 18 '16 at 14:58
43

It happened to me also, but I realized that the script had been included twice because of a bad merge.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
Charles HETIER
  • 1,934
  • 16
  • 28
  • In asp.net mvc I missed I had a bundle that included all js of a folder and I created one more for the single file resulting 2 inclusion of the same file – Darion Badlydone Feb 26 '15 at 11:14
  • I included the same script in both laravel layout and dynamic page. Removing the inclusion in the dynamic php file solved the problem for me. – Prasanna Kumar Jul 10 '18 at 18:05
  • Thanks for mentioning this. It's quite obvious, but your answer made me double check my includes, which solved the problem ;) – florieger Oct 04 '19 at 12:05
  • Yes the same issue happened to me that accidentally included same script twice. – RKM Sep 21 '20 at 14:09
39

This happened to me when using KendoUI... invoking a popup window would cause the document.ready event to fire multiple times. The easy solution is to set a global flag so that it only runs once:

var pageInitialized = false;
$(function()
{
    if(pageInitialized) return;
    pageInitialized = true;
    // Put your init logic here.
});

It's sort of hack-ish, but it works.

qJake
  • 16,821
  • 17
  • 83
  • 135
18

Make sure you don't include JS file twice. That was my case

kakauandme
  • 191
  • 1
  • 3
3

You might consider to use

window.onload

instead of

$(document).ready
hvdd
  • 514
  • 4
  • 7
  • 1
    Just wanna say that this worked for me. Working with google maps, somehow my stuff fired twice, but window.onload instead of document.ready worked for me, so thanks. – balslev Jun 03 '15 at 08:01
2

try putting this in your functions.js to prevent it from being executed twice :

var checkit = window.check_var;
if(checkit === undefined){ //file never entered. the global var was not set.
    window.check_var = 1;
}
else {
    //your functions.js content 
}

however i suggest that you look more into it to see where are you calling the second time.

Mouna Cheikhna
  • 38,870
  • 10
  • 48
  • 69
  • I wanted to avoid something like this as its messy, and i don't like the idea of having to hack this functionality together. Although this may be the only solution that I have if i can't figure this out – Xenology May 23 '12 at 20:22
  • Just wanted to add here, although this is very hacky, it is also incorrect. The syntax should be changed to "if (typeof checkit === 'undefined')." Typeof always returns a string. – Zach Pedigo Aug 08 '19 at 19:37
1

I had a similar problem when I was trying to refresh a partial. I called a return ActionResult instead of a return PartialViewResult. The ActionResult caused my ready() to run twice.

1

There is a possibility to encounter this problem when you add same controller twice in the html.
For an instance:
[js]

app.controller('AppCtrl', function ($scope) {
 $(document).ready(function () {
        alert("Hello");
        //this will call twice 
    });
});

[html]

//controller mentioned for the first time
<md-content ng-controller="AppCtrl">
    //some thing
</md-content>

//same controller mentioned again 
<md-content ng-controller="AppCtrl">
    //some thing
</md-content>
Charitha Goonewardena
  • 4,418
  • 2
  • 36
  • 38
1

I had a similar issue today. A <button type="submit"> caused the $(document).ready(...) event to fire again in my case. Changing the code to <button type="button"> solved the issue for me.

See document.ready function called again after submit button? here on stackoverflow for more details.

lominart
  • 11
  • 1
  • 1
0

In my case $(document).ready was firing twice because of bad CSS, check if any part of your CSS has background-image: url('');

Posis
  • 1
0

If the iframe doesnt show anything and is used for other reasons (like uploading a file without reload) you can do something like this :

<iframe id="upload_target" name="upload_target" style="width:0;height:0;border:0px solid #fff;"></iframe>

Notice that src is not included that prevents the second on ready trigger on the document.

0

I had this problem with window.load function was executed twice: The reason was because I had reference to the same javascript-file in the main page as well as a .net usercontrol. When I removed the reference in the main page, the load-function was only executed once.

0

I had this happen to me this morning... and what I discovered after closely examining some html code in a jquery modal form that I had recently manipulated, that I'd accidentally removed a closing table tag. I haven't taken the time yet to fully understand why that caused the document.ready function to be called twice, but it did. Adding the closing table tag fixed this issue.

jQuery JavaScript Library v1.8.3 (yes, it is a legacy app)

user3232196
  • 169
  • 1
  • 5
0

My problem was that I had tags referencing my JS file in both my index.cshtml file AND my _Layout.cshtml. This was causing the document.ready function to fire twice, which was causing DataTables to bomb.

CaptainGenesisX
  • 328
  • 3
  • 10