iPad safari bookmarklet - why does it require 2 taps? - javascript

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.

Related

JavaScript getElementsByTagName not working correctly

console.log(document.getElementsByTagName("input").length);
is printing out 0. I have found many suggestions online saying that the page is not loaded, but this is not the case. I am running the code via the console on a loaded page (and I have already tried onload). But here is the catch:
The first time I load the page and run it on a computer, the code works correctly and finds all the input elements on the page. However, once I run the code, if I refresh the page, it will always return 0 from there on out. If I switch computers and run the same code, it works fine ONCE and then stops working on refresh.
Furthermore, it's not just limited to "input". It happens to everything (i.e. "a"). Basically I can no longer find ANY elements on the webpage, but they're definitely there. I can inspect the page and look at all of them.
What could be causing this? Is the website blocking JavaScript for me once it sees me using it? If so, what can I do to prevent this from happening?
It's just a simple survey website for my school.
It seems that the title of the tag is always capitalized, as in all these examples:
https://www.w3schools.com/JSREF/met_document_getelementsbytagname.asp
So your code should look something like this:
console.log(document.getElementsByTagName("INPUT").length);

Javascript: How to single-step site initialization?

Short background: I'm pretty new to Javascript and currently interested in customizing third-party websites to my needs — i.e. write scripts for Greasemonkey and the like. Often those sites are bloated with libraries like Jquery, Bootstrap, etc. which makes it even harder to figure out how exactly they work.
When I analyze a new website and want to know what code gets executed, I can use Firebug to create breakpoints or watchpoints and then single-step through the code. However, this does not work for code that already runs while/when the website first loads. How can I single-step through this part? Basically I'm looking for a way to set a breakpoint to the point before even the first Javascript code is executed.
If there are better tools for this than Firebug I'm all open for suggestions. Please keep in mind that I do not control the website, so changing the site's code is out of the question.
If it's enough for you to stop at the load event of the page (normally some code gets executed before that event), you can do the following:
Switch to the HTML panel and there to the Events side panel.
Scroll down to the section saying Other listeners for Window
Right-click the function under the 'load' event (might be one with an arrow besides it) and choose Set Breakpoint from the context menu.
Note: There might be a 'DOMContentLoaded' event handler, which is called before the 'load' event. So, if that exists, set the breakpoint at that function.
Reload the page.
Here's a screenshot of that menu:
As mentioned above, normally some code is already executed before the 'load' event is fired, like libraries getting loaded or some global variables being initialized. Though as far as I know, there is no option in Firebug (or other browser developer tools) to stop the script execution at the very first executed JavaScript statement.
But it's normally still quite easy to set a breakpoint at that line. It just requires some manual searching:
Inside the Script panel select the first script called Inline from the Script Location Menu (the third toolbar button from the left).
Search for the first JavaScript line, or, if there is no inline JavaScript, select the script within the first <script> element from the Script Location Menu.
Set a breakpoint at the first line of the script.
Reload the page.

Finding out which Javascript methods are never called

I have a load of code, and I think much of it is deprecated with numerous methods that are never called. I would like to know which methods in this code will never be called, either as a result of button clicks or via other methods. I could go through and comment out the suspicious methods one-by-one and test the code, but is there a better way?
I am using Visual Studio 2012, and I have tried using JS Lint but that doesn't seem to tell me what I want to know. I really like the Code Analysis for C# and SQL that VS2012 does, but it doesn't do this for Javascript. What should I use?
Open your JS file as the script in a webpage in Chrome. Just surround your JS with an html and script tag:
<html><script>
var mycode = goeshere();
</script></html>
Once you open it in chrome, right click anywhere on the page and click 'Inspect Element'.
Alternatively you can just press CTRL+SHIFT+J to bring up the console.
Once the pane opens, click on the 'Profiles' tab.
Select "Collect JavaScript CPU Profile", and follow the steps to run it.
This will give you timing counts per function call. Try to work through as much of the functionality as you can, then once you are finished look at the function timing counts. Any call with 0 time probably wasn't called. This should at least give you a starting point.

Execute JavaScript function after SharePoint is initialized

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 :)

How to debug DOM manipulation by jQuery?

I'm working on an website with some dynamic jQuery content.
If the user pushed a button ("show menu") on the page, an javascript function runs. Let this function call loadMenu().
The loadMenu() function loads a menu (web conent) from server using ajax. Part of this loaded code is javascript/jquery. 2 functions of this code make some elements on the page draggable, 2 other functions make some elements on the webpage droppable. These functions are all started at $.ready-Time (if the DOM is ready).
All this works fine.
Now i added an "MenuAlwaysVisible" feature. This means: if the web-page is loading and finished (ready) the user doesn't need to press the button "show menu", because the javascript loadMenu() now fires automatically, if the page is ready
The problem now is, it looks like, the draggable handler are attached and worked as defined, but droppable does not work.
I'm not sure, but probably the droppable function runs on a time, where the DOM elements doesn't like to be droppable? Ore maybe some other jQuery codes overrides this? (but there are no other droppable elements on the page)?
So the question is: how to analyze that problem: how to debug DOM manipulation, using Windows and Firefox/Firebug or Safari, Chrome .. whatever...
Thank you!
One debugging trick I have found endlessly useful for dealing with JQuery is the insert obvious code trick. Slap in a .hide() command on some obvious, identifiable part of the page, and see if the code ever runs. Lets you track which code pieces are not behaving as intended, and which are simply never being used in the first place.
To answer my own question: i did not found any alternatives way than using firebug and console.info() or console.warn() to debug the code.
Thanks # all for the comments

Categories