Handling browser native click before dom:loaded - javascript

I have an issue with Cross-Browser native events vs CallBack events.
I have an HTML link "Click Me" with a given href="". On dom:loaded I attach a function to this link (to do Ajax Stuff).
JavaScript code is loaded at the end of the page to follow YSlow Recommandation.
Issue:
If you load this page really quickly (pressing F5) then click on link then
the alert() is not called
the link is followed (reloading the page)
It happens when the server lags. In fact the page has not finished loading and the browser execute the code.
Demo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
</head>
<body>
Click Me
<!-- According to YSlow Recommandation load at the bottom -->
<script src="../js/lib/prototype.js" type="text/javascript" language="JavaScript"></script>
<script>
/* <![CDATA[ */
document.observe('dom:loaded', function() {
$('action').observe('click', function(event){ alert("click"); Event.stop(event); });
});
/* ]]> */
</script>
</body>
</html>
Turn Around:
A turn around is to add onClick="return false;":
Click Me
It works for lags but not for quick click. And I don't like this kind of turn around because my goal is to remove the onclick on all <a href="">

You could look into this:
JQuery has a handy little function that
launches your javascript as soon as
the Document Object Model is ready…
which happens before the page has
finished loading.
$(document).ready(function(){ //
Your code here...
});
via
You could also put a big disabled div in front of everything while the page is loading to forbid clicking, but I wouldn't recommend it.
Not sure if I got your question right, let me know if I didn't

We have done many many test on our CMS on many browsers.
Sorted by speed:
JavaScript can't execute before a really fast click
onclick="return false" works fine in most case
JavaScript doing 2.) onLoad is too slow but could be enought
DIV using as shield brings other issues and is not a good choice

It seems like you have things pretty well in hand, and all you're looking to do is create some links which do nothing in areas where graceful degradation is not possible.
In these cases I suggest a link with the following format:
Linktext
This link should functionally do absolutely nothing with javascript enabled or disabled.
Important Notes
The number zero in the void is absolutely necessary. Internet Explorer will complain otherwise.
The use of "javascript:void(0);" is strongly discouraged by Microsoft because odd things can happen. To avoid the majority of the bugs, do not wrap anything but text in your void(0) links.
Before you make a decision make sure to carefully consider if adding "javascript:void(0);" is really a better solution than adding an onclick which returns false.
On removing the href attribute:
Removing the href attribute from a link is valid XHTML. Despite being valid XHTML, your link will lose its automatic link styling. No more underline, no more colors, no more hover, and no more automatic color change if the link is visited.
You can't fix the lack of styles with CSS either due to the spotty support of :hover in Internet Explorer.

Related

Alert does not trigger, JS is not detected

I think I might be going crazy at this point. I had an ASP page working yesterday, and came in today to Firebug telling me it cannot detect the JavaScript on the page. Love it when things change after not touching them.
So I start trying to figure out what is happening. I tried slimming down the code, this answer, restarting Firefox, saving the page under a new name and loading the new one, and adding a ridiculous amount of code I generally consider unnecessary. I even tried removing everything from the page and changing it to this:
<script>
alert("yay");
</script>
Does not trigger alert, and Firebug says "No JavaScript on this page". I've been looking for explanations for almost 2 hours and cannot figure out what is happening. I know I did not deactivate anything because other pages will show JavaScript and function properly. I also know that no add-ons are causing it.
I am using Firefox 28.0 (also tried on 27.0.1). Opening the page in Chrome triggers the alert.
(Damn I meant to post this as a comment).
As you responded I'll re-popualate...
I create jsfiddle,
<body>
<script>
alert("yay");
</script>
</body>
Also ensure your browser has javascript enabled.
You should follow the instructions on the Firebug's first aid page.
I assume it's either some Firebug setting or a conflict with another extension. (I see at least YSlow and FlashFirebug installed.)
To check that you can create a new profile and just install Firebug.
Closing the tab and opening the same link in a new tab seemed to resolve the issue.
I'm not sure if any of the prior attempts factored in, so I will list them as well. To be clear, none of these worked, but may have paved the way in some fashion.
Restarting Firefox
"Clear Activation List" on Firebug
Save page under new filename and load the new page
Uninstalling add-ons (all of them)
Create new profile and load page on that profile
Add a <!DOCTYPE html> to the top
Add type="text/javascript" to script tags
Add charset="utf-8" to script tags
Add <meta charset="utf-8"> in <head>

Dynamically loading jQuery mobile causes IE to minimize

Okay, this is by far the weirdest bug I have ever encountered. It's pretty straightforward though. If I load jQuery and then jQuery mobile dynamically in any version of Internet Explorer, the actual IE window minimizes. This happens in all versions of IE through IETester, however, if I run the full version in IE9, it kicks compatibility mode and for some reason doesn't minimize.
I've tried various ways of loading the scripts (commented in the example code), all resulting in the same behaviour.
Why is this happening? Is there a way around it?
http://jsfiddle.net/Xeon06/RCsuH/
This is a known issue in jQuery mobile. The offending line is jquery.mobile.navigation.js:913.
// Kill the keyboard.
// XXX_jblas: We need to stop crawling the entire document to kill focus. Instead,
// we should be tracking focus with a live() handler so we already have
// the element in hand at this point.
// Wrap this in a try/catch block since IE9 throw "Unspecified error" if document.activeElement
// is undefined when we are in an IFrame.
try {
$( document.activeElement || "" ).add( "input:focus, textarea:focus, select:focus" ).blur();
} catch(e) {}
There's the call to blur() that's sending IE windows to the back of the stack.
As a workaround, you can avoid this by placing the script tags physically in the <head> of the HTML.
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/mobile/latest/jquery.mobile.css" />
<script src="http://code.jquery.com/jquery-1.6.2.js"></script>
<script src="http://code.jquery.com/mobile/latest/jquery.mobile.js"></script>
...
Placing the script tags elsewhere in the document or inserting them via script triggers the bug.
This Fiddle demostrates the workaround in action. Note that this only works in a top-level document. If the document is in an <iframe>, the bug will still appear. Thus, if you open the JSFiddle editor in IE 7/8, it will still get sent to the back; but if you open just the rendered HTML, it will not.
My attempt at "fixing" it: http://jsfiddle.net/RCsuH/6/
#josh3736 was almost exactly right, somewhere in the code it is firing off a document.body.blur() which causes the minimization of the window.
My fix simply replaces that function with a no-op function. I was unable to get the script tags to fire an onload when they finished loading, so replacing the function (if necessary) is left up to you.
However all of this seems to be a bug in the jQuery Mobile library, and thus you should probably file a bug report with them. However, I'm not sure it will bother them too much that there is a bug on IE for a framework that is intended for mobile phones/tablets.
Note: This is horrible, horrible code that replaces native functions. If it is possible, don't use this.

Delphi, EmbeddedWB/TWebbrowser - jQuery not executing

I am using EmbeddedWB (A TWebbrowser extension) to do like a "live preview" of some dynamically generated content.
I am trying to add jQuery into the mix, so I can get some fancy effects going on, however since IE9 always asks "Allow blocked content" for each and every damn page, a dynamically generated one (Webbrowser.LoadFromString) certainly wont be allowed to have fun. To put it simple: It wont allow Javascript execution.
I tried adding a SecurityManager to my TEmbeddedWB, however that did not do it either. I tested my dynamic code in Firefox, and in IE9, and it works (of course, in IE9 I have to allow first, which was how I found it was a security issue).
Is there a painless way to get around this, without having to manually go into IE and tweak something? Or am I completely wrong about the cause of the issue?
EDIT: After trying this article's method, IE does not ask if it should allow stuff anymore, however my script is still not being executed within my TEmbeddedWB/TWebbrowser..
EDIT 2: Okay, by removing the jQuery code, and displaying a plain Alert, I am forced to conclude that JS is now being executed, however jQuery is not.
EDIT 3: Here is the (stripped down) HTML code that my app generates, where jQuery is not working in my EmbeddedWB/TWebbrowser control - however, it works in Internet Explorer 9 itself:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<script type="text/javascript" src="file://C:\jQuery.js"></script>
</head>
<body>
<center>
<p>
Some stuff here!
</p>
</center>
<script type="text/javascript" language="javascript">
$(document).ready(function(){
alert('I Am jQuery!!!!');
});
</script>
</body>
</html>
EDIT4: I have also tried switching the src to a Google Hosted jQuery, and that did not work either. Removing the Metatag did not fix it either. Just letting you know of stuff I tried before you waste time on suggesting it :)
EDIT5: By navigating to a site that uses jQuery (Webbrowser.Navigate) the site was working as expected. However when doing it from my local test.html, or by doing .LoadFromString();, it will not work.
Will not work = jQuery code not executing.
It seems to work if you use correct URL for the jquery.js file:
<script type="text/javascript" src="file://C:/jQuery.js"></script>
<script type="text/javascript" src="file:///jQuery.js"></script>
or a relative path, you can also omit the file:// protocol:
<script type="text/javascript" src="../../jQuery.js"></script>
The above works when you load the HTML from a file. The question is however, if content from memory and javascript from file system is not considered crossing a security context boundary and rejected for that reason by the embedded browser. In that case, embedding jquery directly in the HTML content (using the <script> tag) should work.

Adding favicon to javascript Bookmarklet (uses window.open)

I have a bookmarklet that launches a window.open javascript function to open a small window with my bookmarklet -- an external feature used to communicate between any visted site and my server. I'd like for a favicon to show up when the bookmarklet is added to the bookmark toolbar. I realize that the bookmarklet is javascript, there is no domain tied to it so it's going to be either difficult or impossible to achieve this goal.
My understanding of the problem:
Favicons are easy to understand, a link within the head of an HTML doc. The browser can pull this when bookmarking an actual site by reference. However, as you see my bookmarklet is ran off a javascript launch code where there exists no HTML, therefor no link to a favicon. I'm not ready to give up yet though, I feel that there's some injection that can be made...
As of now, the bookmarklet launch code looks like this:
Current Script -- bookmarklet, no favicon (note all code is formated with line breaks -- won't work in all browsers, normally its one line)
javascript:void(window.open(
'http://mydomain.com/bookmarklet/form?u='
+encodeURIComponent(location.href)+
't='+encodeURIComponent(document.title),
'test','status=0,toolbar=0,location=0,menubar=0,
resizable=false,scrollbars=false,height=379,width=379'
));
The closest thing I've found to a solution is as follows, but it doesn't open a new window -- just creates a new tab with the html as the page:
Working favicon, no bookmarklet window
javascript:'<!DOCTYPE html>
<html><head>
<title>Hello World</title>
<link rel="icon" type="image/png" href="http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png" />
</head>
<body>Hello World</body>
</html>';
I have tried a combination of the two but it didn't seem to use the icon. I'd be curious to know if anyone can see a type of workaround.. I think it could be possible, I just don't think it's set up correctly as I've been trying.
My hybrid of the two -- bookmarklet but no favicon
javascript:'<!DOCTYPE html>
<html><head>
<title>Hello World</title>
<link rel="icon" type="image/png" href="http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png" />
</head><body>Hello World</body></html>';
window.open('http://mydomain.com/bookmarklet/form?u='
+encodeURIComponent(location.href)+
'&t='+encodeURIComponent(document.title),
'test',
'status=0,toolbar=0,location=0,menubar=0,resizable=false,
scrollbars=false,height=379,width=379').void(0);
What I did was use the html structure before firing window.open(), this successfully opened my bookmarklet in a new window, but no favicon showed up for the bookmark icon.
Logical Solution:
My thoughts on this would be to have the bookmarklet point to a page that is simply an HTML file with a favicon link and the launch script in the <head>. However, I don't want this opening in a new tab with a blank HTML file that then launches a popup.. Workaround..?
There exists a similar question but I did not seem to find the answer I'm looking for:
How to have favicon / icon set when bookmarklet dragged to toolbar?
Source for the working javascript favicon (no bookmarklet however):
http://www.tapper-ware.net/blog/?p=97
I'd be interested in what your current knowledge/thoughts on this would be
I tried and retried, and my first conclusion was: "It can't be done (at least not in FF4 on Ubuntu 11.04)". You need (I guess) a simple solution for your site visitors (drag&drop, add bookmark with 1 click ...).
I have found a workaround, it does it's job, but it is a little buggy (maybe someone can help fix it).
PROS:
add a icon to the bookmarklet
it uses windows.open
doesn't leave empty pages behind
CONS:
it reloads the current page (instead of leave a page behind)
Can't make Firefox POP-ul blocker allow "javascript:" generated HTML page to load POP-ups, so you need to hit allow every time
This is the code:
Bookmarklet
This is a link that you put on your page, the user needs to drag&drop this link to the bookmark bar (you can use something like Add Bookmark Script for adding it as a bookmark with 1 click), The bookmark has no icon until the user click's it at least once.
So how it supose to work:
1. redirect the user to the generated HTML page from the bookmarklet (that makes the ICON posible)
2. onLoad open the window you need using "windows.open"
3. redirect the page back using "history.back(-1)"
In theory everithing happens so fast, that the user does't see the new page, just that the current page is reloading, and a new windows appear.
The problem:
1. I use setTimeout for history.back beacause window.open is blocked by Firefox, so I need to click allow every single time (if somebody can fix this ... we have a chance of using this, develop it further :) )
I know THIS is not a reliable solution, but this is the only solution I've got so far.
Hope this helps a little. :)
Some of the things that I've tried that might possibly get you going a bit more:
Append a new link element to the current document:
javascript: var newLink = document.createElement('link');
newLink.setAttribute('rel','icon');
newLink.setAttribute('type','image/png');
newLink.setAttribute('href','http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png');
document.querySelector('head').appendChild(newLink);
void(0);
Note that I was using the querySelector due to IE testing (though works in modern browsers as well). With Chrome and FF, I kept getting invalid character when trying to create the element, so I had to do piecewise attribute setting.
Tried using base64 encoded image string using the "data:image/png;base64,iVBORw0KGgoAAAA..." URI schema, but that didn't help anything due to the fact that I still had to set it to the current HTML text (which I could do, but ran into the same problem as you above of no bookmarklet).
Maybe this can't be done due to cross site scripting concerns? Not sure... Either way, really curious to see what you come up with (if you manage to come up with anything).
"I don't want this opening in a new tab with a blank HTML file that then launches a popup.. Workaround..?"
If what you after really is the visual effect, you can try launch the blank HTML in hidden iframe, then launch the javascript.
Hope that helps

Display "Enable JavaScript" message only when JavaScript is disabled

I want to display to the user a message that says "please enable JavaScript" in the case that JavaScript is disabled. I want that message, and nothing else to be displayed when JavaScript is disabled.
So, to do this, I can put the message in the DOM and hide all other elements with display:none. Then in JavaScript I can set the message to display hidden and show all other elements.
But I get a flicker with this approach. The error message shows up for a while (especially on mobile browsers) before it gets hidden.
How can I minimize the time the error message is displayed for?
You're looking for the <noscript> tag.
Inline javascript has to run before the rest of the document is loaded. You can use this behaviour to add style to the page to hide the desired element, before the element is loaded. This should theoretically stop FOUC across all and every browser (including mobile). Here's an example of a standalone HTML that shows a message to those with no javascript. This technique also takes care of what Hussein was mentioning about Firewalls blocking javascript:
<!doctype html>
<html>
<head>
<title>No FOUC</title>
<script type="text/javascript">
document.write('<style type="text/css">#no-js { display: none; }</style>');
</script>
</head>
<body>
<div id="no-js">You don't have javascript, BOOOO</div>
</body>
</html>
You can do this. If JavaScript is disabled it will show the message "JavaScript Disabled"
<p id="jsDisabled">JavaScript disabled.</p>
<script type="text/javascript">
function hideScriptDisabled() {
document.getElementById("jsDisabled").display = "none";
}
hideScriptDisabled();
</script>
If that is creating a flickering problem, use something like this,
document.write(".jsDisabled { display: none; }");
See 1 Way To Avoid the Flash of Unstyled Content
To avoid javascript disable problem.
before starting any writing on your webpage just put the below code.
<!-- saved from url=(0014)about:internet-->
You have to never ask any question to end user.
First try it.
You really can't. The flicker is just the way it is...especially on slow mobile devices (namely Nokia...OH HOW I HATE NOKIA!)
The only other option is to load a splash page first. In the HEAD add a meta refresh of several seconds that will refresh to a 'turn on javascript error'. On the BODY, add a javascript redirect that should trigger immediately.
You will still have a flash, and of course, one more page request to the server. But it may be a 'prettier' flash.

Categories