Execute JavaScript function after SharePoint is initialized - javascript

I have a custom JS script which I load into SharePoint and have problems to get my init method executed after SP is finished with its own initializing.
_spBodyOnLoadFunctionNames
I tried the "official" way first and added my function name to the list of executed functions after body load with _spBodyOnLoadFunctionNames.push("myInitMethod"); but that does not fire on every page load, I can't rely on that.
ExecuteOrDelayUntilScriptLoaded
Then I tried to use ExecuteOrDelayUntilScriptLoaded(myInitMethod, "sp.js"); function but it does not fire on every page load either.
Both ways work - but not every time. I assume that my script is loaded sometimes before the SP is initialized. This happens mostly on Chrome but on IE as well.
How can I make sure that my script is executed when SP is ready?
Note: There is an interesting behaviour when the page is loaded and the SP object is not fully initialized (the registered functions in ExecuteOrDelayUntilScriptLoaded has not been called): As soon as I click on the "Navigate Up" anchor in the page (where you can see the hiarchy of the subsites) the following files gets loaded and my init function (registered in ExecuteOrDelayUntilScriptLoaded) gets called!
core.debug.js
sp.core.debug.js
ScriptResx.ashx
sp.ui.dialog.debug.js
sp.runtime.debug.js
sp.debug.js
So everything is fine after that click - but why not on pageload as it should be?

It seems that this behaviour is related to some issues between SP 2010 and Google Chrome - I don't have this issues on other browsers.

This is a timing issue that somehow occurs only on non-IE browsers.
See http://withinsharepoint.com/archives/256 for an explanation and very easy fix.

Hey I came across your question when I was looking for a way to delay my JavaScript from loading until sp.js has.
The reason your code you provided works some of the time is because (some of the time) SharePoint doesn't initialize all of it's codebase. This is a big problem in Google Chrome, but can happen in other browsers (non-IE) as well. To work around that particular issue you can do something like this:
if (typeof(_spBodyOnLoadWrapper)!='undefined'){_spBodyOnLoadWrapper();}
I put mine inside of $(document).ready().
And thanks for answering my question :)

Related

JS Script execution order on displaying from cache

I am writing a rail app making trees, with bootstrap and jsPlumb.
I have this problem, when displaying a page for the first time, everything works perfectly. When I go again on a page, some code is not properly executed.
This happens with both jsPlumb and bootstrap-tagsinput: a simple tagsinput on a page is not displaying properly.
If I hit refresh, then the page loads properly again.
I tend to think this is related to the fact that when I display a page with some cached elements, some of the script are not executed, or are executed in the wrong order, but I have no clue about it, since I can't see any error.
Hence the questions,:
How can I check that everything is properly executed (i used the console.log, the function are called)?
Is there anything to know about the way the cache may have an effect on script?
How can I debug this type of problem?
Thank you!
I found the answer, this was due to turbolinks, which handles some of the caching on the server-side. It was a holdover gem that I suppressed, and the problem is gone.

iPad safari bookmarklet - why does it require 2 taps?

I have a bookmarklet like this:
javascript:(function()%7Bvar%20x=document.createElement('SCRIPT');x.type='text/javascript';x.src='http://tmxhost.com/mail/clippad.js?'+(new%20Date().getTime()/100000);document.getElementsByTagName('head')%5B0%5D.appendChild(x);%7D)();
But when I tap it nothing happens until I tap it a second time, then it writes the DOM. Anyone know why?
The bookmarklet appends this script to page: http://tmxhost.com/mail/clippad.js
That script has two parts. 1.) Add jQuery to page. 2.) Use jQuery.
The problem is that there is no check that jQuery has loaded before the second part is run, so usually the second part will fail on the first try.
When you click the bookmarklet the 2nd time, jQuery has finished loading, so the second part runs as expected.
There are some good tools and tutorials for using jQuery in a bookmarklet: https://www.google.com/search?q=jquery+bookmarklet
Another point to consider is that using $(document).ready is generally pointless in a bookmarklet because a bookmarklet is almost always used after the document is ready.

Javascript firefox issue

I developed a .htm document with an in-built script for javascript to run a program. In google chrome, the program works fine, but I got a beta test complaint that it didn't work on firefox 14.01 or opera. On testing with firefox 14.01, I can confirm it doesn't work (I assumed opera to be the same). I cannot insist the audience upgrade their browsers, as this is supposed to be widely compatible.
Doing a little tracing of the issue, I installed Firebug, which, on clicking the Javascript button to generate a coordinate the first time, it worked (clearly showing the function is defined and exists), but the second time, Firebug complained that:
"ReferenceError: GenerateCoord is not defined".
This wouldn't be so ironic if it only did this after generating an (encrypted) coordinate (thus calling GenerateCoord that is supposedly 'undefined').
If one looks in the code, one can clearly see that the function GenerateCoord is clearly defined before it is called. I would say firefox has an 'onclick' issue, but then it begs the question why did it work the first time I clicked it (calling GenerateCoord via 'onclick') but not the second?
Reloading the file allows the button to work the first time, and the first time only. I am baffled as to how firefox can call a function one time that it then says is undefined the next. Am I missing something here?
Javascript and HTML code can be viewed here:
http://pastebin.com/4qykTfEW
-
How do I solve the problem, and is there an easier solution than re-writing the code to avoid onclick (that seems to work in certain circumstances but not others)?
The problem is that using document.write overwrites the entire HTML page, thus inadvertently removing the GenerateCoord script. I'd suggest appending the link to the document (in ShowTarget) rather than attempting to re-write it.
For example, have a container element where the link should be:
<div id="links_container"></div>
Then to append the links, use:
document.getElementById('links_container').innerHTML = Link;

IE never stops loading image

I have a page that creates a static google map based on data retrieved from a database using PHP and displays it using a javascript function that is embedded inline within the code.
The javascript function is automatically executed when the page loads or refreshes and also will execute when the user explicitly requests a map (onclick) to be displayed.
It works exactly how I expect on FF.
On IE8 it also works exactly as I expect, up to a point. The problem is it never seems to return from loading the image although the image is, in fact, fully displayed on the screen with all the map locations. The real problem is there are other javascript functions on the page that never get called because of the infinite load operation.
If during this prolonged loading process the user explicitly displays a map it will display correctly AND the subsequent javascript code also executes, effectively resetting the display.
BTY, if I put an alert just after the return from the javascript function it triggers but the next function, that needs to load an image never loads its image.
I know I am probably looking for trouble mixing PHP and javascript but I have tried to be real careful to respect the client/server relationship and make sure that everything on the server (php) is finished before the page containing the javascript is actually loaded.
Unfortunately, the application doesn't lend itself to creating a simple demo to reproduce it and I'm working under an NDA so I can't point you to the page.
Any thoughts or debug suggestions would be welcome.
I don't know if this is THE answer but I have a work a round.
In the javascript I thought I was doing the right thing by destroying any existing image and creating a new image with:
image = document.createElement ('img');
If I remove this code and assign the new image to the existing image object, overwriting the src attribute, everything works for both FF and IE.
Does IE fully support document.createElement ('img')?
The thing I don't get is that the code works fine when the user explicitly selects the function so I know that IE supports createElement in some situations but it's not clear why it doesn't work all the time.
My function now works in both IE and FF.

Making Firebug break inside dynamically loaded javascript

I'm looking for a way to debug a dynamically loaded jQuery document.ready function.
Obviously I can't just bring up the script panel and add a breakpoint with the mouse since the function does not exist there.
I've also tried adding "debugger;" to the function (without the quotes), but that did not do anything. I have ensured that the function is actually executed while I tried this.
Thanks for your help,
Adrian
Edit: I just noticed that Firebug actually breaks on debug. However, when it does so on a dynamically loaded script, it does not bring up the source code of that script as usual. Plus, the call stack ends right below my own code. I can bring up the implementation for document.ready via the call stack, but that does not really help. Is this a Firebug bug or have I missed something?
I just worked on this similar question. The solution involves adding the word debugger twice; once at the top of the external file and one more time at the top of the function that needs to be debugged.
I noticed that if the debugger word was used only once, it did not work. Example:
//myExternal.js
debugger;
function myExternalFunction(){
debugger;
/* do something here */
}
You might try placing a break point where the event is called, and then instead of click "Play", choose "Step Into" (F11). I don't have a test case in front of me, but I think this may work.
I don't know if you ever got this figured out, but in case someone else needs it...
I got around this by moving the code I wanted to debug to an external file that was linked from the main page.
In my case, I had default.aspx loading services.aspx into a content div using jQuery AJAX. Services.aspx in turn, was loading jQuery UI tab elements using AJAX from a webservice that was providing it data. The webservice code was in a file called data.js which was linked from default.aspx. I needed to debug the code that was in the header of services.aspx (that loaded the tabs with data), but couldn't ever see it in any of the available inspectors. I just moved the code I needed to a new function in data.js and called it from the header in services.aspx.
I hope that makes sense to someone who needs it!
Just encountered same behavior (Firebug ignoring debugger; statement in dynamically loaded code) in Firefox 5.0/Firebug 1.7.3.
Worked around by detaching Firebug window ("Open Firebug in New Window").
There's also a 'debugger' keyword that's supported by the IE JScript debugger, and Safari's Web Inspector, so i would be surprised ifit wasn't supported in firebug.
Basically:
// mydynamicallyloadedfile.js
... // do stuff
debugger; // triggers debugger
... // more stuff
And i would expect firebug to break at the debugger keyword

Categories