View Full Version : Unobtrusive Bookmark Script Works But Not Properly

Jules Manson
12-23-2005, 07:42 AM
My crossbrowser bookmark script does not wait for the onClick event to activate. The bookmark dialog box opens immediately when the page loads. It will not work at all if I remove the onload="bookFav()" from the BODY tag. It is supposed to wait for an onClick mouse event. My intent in writing this as I did is to completely seperate behavior from presentation and structure. My goal is to eventually link this script externally via a common javascript library file. I tested it with Internet Explorer 6.0 on Windows Me. Please, no solutions which require adding inline javascript to my bookmark link. I already know how to do that. I need to make this unobtrusive so that nonprogrammers can easily manage and edit HTML files. Please examine my script and see why it is not waiting for the onClick event. Thank you in advance for your help.

function bookFav() {
if (!document.getElementById || !document.all) /* object detection to prevent errors */
{alert("Please use your browser menu to bookmark us!");} /* for non NS,FF,MSIE */
else {
var el = document.getElementById("bookmark");
myURL = window.location.href; /* gets URL of page to bookmark */
myTitle = document.title; /* gets title of page */
el.onClick = addFav(myURL,myTitle); /* this should initiate the script */
function addFav(aURL,aTitle){
if (document.all) /* is this MSIE? */
{window.external.AddFavorite(aURL,aTitle);} /* then call bookmark for MSIE */
else if(window.sidebar) {window.sidebar.addPanel(aURL,aTitle,"");} /* else call bookmark for NS&FF */
return false;
<BODY onload="bookFav();">
Please <A id="bookmark" href="#">bookmark</A> this site.

Philip M
12-23-2005, 09:05 AM
<BODY onload="bookFav();">
causes the function to load and run when the page loads.

I don't understand why you do not wish inline JavaScript in your bookmark link as this is what is required.

Another first-time poster taking people's help for granted by thanking them in advance. In normal polite society people offer thanks afterwards.

Jules Manson
12-23-2005, 04:26 PM
Dear good people:

Allow me to retort to Philip M's "help" before others are pursuaded by his very flawed response and not help me at all. (1) Not doing a BODY onload causes the function not to work at all. (2) All inline function calls as well as all events can be placed inside the javascript itself. If you don't believe me please visit The Behaviour Layer (http://adactio.com/atmedia2005/). By taking inline scripts out of the HTML one can for example not have to go through hundreds of pages to edit a single function. A programmer can simply edit the javascript in one external js file. This is analogous to using CSS in a single external file to edit the look and feel of an entire web site. This bookmark script will be a model for many other functions. (3) Who says I wouldn't have thanked the replier afterwards? I was only trying to be polite at all levels of this enquiry.

If you do wish to help me please do not do as Philip did. Please copy and paste the entire code given to a new htm/html file to see what it does. He obviously took this opportunity to attempt to humiliate me a little bit without knowing all of the facts. Anyway this isn't about mud slinging. I just wanted a little expert help from someone out there who understood the concept of unobtrusive DOM scripting. Again I thank you all in advance for your help.



12-23-2005, 09:30 PM
Actually I see both points-of-view...

When I first read this question, I wasn't quite sure of what you meant by not wanting inline js. Granted, I knew you didn't want href="javascript:var hi='Hello World'; alert(hi);", but rather wanted a function to be able to be kept in a separate .js file where it could easily be modified. But even a function call in an event (eg onclick="myFunct();") could be considered to be inline js, and I was of a similar opinion as Philip that you could keep the js function "unobtrusive" by storing its definition inside a separate .js file while still using inline js to call it. I think we both were missing exactly what you were going after; that link (which I would recomend you keeping for your signature :thumbsup: ) was a very good description as to what you were going for.

I was also confused as to what you were trying to ask; I was under the impression that you were confused about the different event calls...
It will not work at all if I remove the onload="bookFav()" from the BODY tag. It is supposed to wait for an onClick mouse event This sounds like you were attempting to call onclick="bookFav()" (maybe even <body onclick="bookFav()"> ) and it wasn't working the way you expected. Thus I feel that Philip's answer made sense; he stated what you should expect to happen when an onload event is called. Once again, that link you posted cleared up what exactly you were asking.

About your comment on Phillip's help:

He obviously took this opportunity to attempt to humiliate me a little bit without knowing all of the facts.
Firstly, I do not think he was trying to humiliate you. Rather I felt that his help was genuinely offered, including his aside about first-time posters. His comment about taking people's help for granted is a common first-time poster problem. All too often on this (and other) forums, you get messages like "URGENT!!! I need to have this script turned in tomorrow. Thanks in advance!" and a few hours later "Come on! I need Help!!!". Having that be your first post didn't help matters either; for all we knew, you may have been one of those annoying first-time posters that do take our aid for granted, instead of someone that is just trying to be polite ahead of time. See the link in my sig. about asking a good question to see the pit-falls that many posters fall into (even veterans, like myself (http://www.codingforums.com/showthread.php?t=74434)! :o)
Secondly, I think you did hit the nail on the head with the second part of that sentence. Both of us didn't know all of the facts. We didn't know about the site you linked to, nor what you actually wanted to accomplish by "unobtrusive" js. Again, going back to my link about asking a good question, all too often people ask for a solution that will fix what they believe will be a solution to their immediate problem without mentioning what their overall goal is. Without your link (or a good explanation of what your overall goal was) we were missing the forest for the trees (I kept looking at your script and couldn't see any syntax errors, so it was difficult for me to know what you were trying to do, except for the misconceptions I had as mentioned above).

Phew! I think we're all sick of my rant! On to an answer to your question...

One thing you may want to do to make the js even more unobtrusive would be to call bookFav() inside the <script> tags as well:

(or document.getElementsByTagName('body')[0].onload=bookFav; if you want...)

Notice how functions get assigned to events -- both use the pointer (ie variable / function name) instead of calling the function. If I had written:

this line would have first called the bookFav() function, and then stored that result in window.onload. But by using just the name without the (paren.s), the pointer to the function gets assigned to the event handler. So inside your code:

el.onClick = addFav(myURL,myTitle); /* this should initiate the script */
you are actually asking for addFav() to run and store its result in the onclick event. To fix this, you would need to state onclick=addFav. However, this functiuon call requires a couple of arguments to be passed, so this won't work either. You'll actually need to place the addFav() call inside of an anonymous function and assign this annonymous function to the onclick handler. Also since the arguments are defined outside (ie you are not passing "a literal string" or something along those lines), you will need to pass those arguments to the annon. function as well. Hense the final code will look like:

el.onclick=function(tempURL, tempTitle) // Assign annon. function to onclick
return addFav(tempURL, tempTitle); // Have onclick call your function
}(myURL,myTitle); // Pass annon function arg's that you want to use

Jules Manson
12-24-2005, 01:10 AM
Dear Pyth007:

Thank you for your detailed and thoughtful response.


(1) I read all three links on your signature. Very informative links. I learned a few things from "How To Ask Questions..."

(2) All the HTML, CSS, and little javascript that I do know was self-taught from spending countless hours searching the web and pulling my hair and beating up on my innocent keyboards in frustration over browser inconsistencies. This is what college trains people to do -- beat up on innocent keyboards that is.

(3) As you suggested I created a signature.


(1) As you and Phil suggested I replaced BODY onload with window.onload.

(2) I applied your anonymous function but now I get errors.

(3) I simplified and rephrased my request for help:

I want the code in this bookmark1.html (http://members.aol.com/oysteinramfjord/bookmark1.html) to behave like this bookmark2.html (http://members.aol.com/oysteinramfjord/bookmark2.html) without adding any javascript inside any tags whatsoever. All javascript must exist inside the head section of the HTML file. This is what I get when I apply the anonymous function solution: bookmark3.html (http://members.aol.com/oysteinramfjord/bookmark3.html). All three were tested with Internet Explorer 6.0 and Firefox 1.5 on Windows Me (yes I know I am laughing too). My ultimate goal is to ensure that this script also works on Netscape, Firefox, and Opera.

12-27-2005, 02:45 PM
I found a logical error in your code...

if (!document.getElementById || !document.all)

...should be with 'and' (&&). You are basically saying, "if you don't understand this method and you don't understand this other method, then just spit out a response to have the user do all of the work" In other words, when testing the scripts out in FF, it would return 'false' to document.all, !'false'='true', thus the entire if-condition='true' and I was always getting the message to bookmark it myself.

As for the errors... In FF, the javascript console stated that I was trying to perform a sidebar operation from an illegal source.... This could be some type of security measure that FF imposes, so this script may not work for FF ater all.... Not sure about the errors in IE, however...

As for why the function is still running onload instead of onclick, I'm stumped... I've tried doing simple things like displaying an alert of the variables passed inside, so that it doesn't trip off the errors, but still no luck.. I'll try looking at how other annon. functions are used to see if I'm making some type of mistake.

Jules Manson
12-27-2005, 03:18 PM
Thank you for hanging in there Pyth007. As you can see a relatively simple appearing script can be challenging even to seasoned programmers. Here are my thoughts on your solutions:

Doesn't this

if (!document.getElementById || !document.all)

mean "if you don't understand getElementById (W3C) or (||) if you don't understand document.all (jscript by Microsoft)" then you should alert user to manually add bookmark? Of course this is still a logical error on my part but after applying your correction (&&) the same problem persists which immediately popups the bookmark dialog on MSIE when page loads. For the sake of simplicity I want to solve the most daunting problem first which is...

"With MSIE how do I force the script to wait for my onClick event handler inside the javascript in the head section of the HTML without adding any inline script to any HTML tags?"

I am attempting to make this script completely unobtrusive. This means that absolutely no javascipt at all is allowed in any HTML tags. Please take a quick look at my signature links for the reasoning behind this.

12-27-2005, 09:47 PM
The if statement should read:

if (window.external && window.external.AddFavorite)

document.getElementById and document.all have nothing whatever to do with whether the code is supported.

As you currently have it coded it will crash in Opera which recognises both document.getElementById and document.all but not window.external

12-28-2005, 12:59 PM
felgall made a good point... the if's should test the method / property you want to use, not some different property that currently goes with a particular browser. For example, it's quite possible that microsoft will try to adhere to W3C conventions better and thus will get rid of (or at least phase out) document.all and so IE-next gen. will return false to that condition. However, the "bookmarking" is definitely browser-specific (or at least W3C hasn't touched this item) so there's a better chance that the browser-specific conventions will stay around longer. Thus testing for the specific application you want to use will give your code "staying" power.

As for the errors, I didn't think that making the onclick methods "listened" to would be necessary (since <a>s usually are triggered by onclick), but maybe because the html doesn't specify it, the onclick won't work until you assign a listener to it... Here (http://www.quirksmode.org/js/events_advanced.html)is a good site that discusses how to do this (actually the entire site is a pretty good resource, not just for this topic, but for others as well). There are some other scripts out on the web that combines MS's method and the other methods together into one function, if you're wanting to go that route.

12-28-2005, 02:59 PM
Boy I feel like an idiot sometimes... :o
Functions run when you put there arguments inside parentheses, even after anon. functions! Thus when I had you do
onclick= function(argList){function stuff}(passedArgList);
the passedArgList would cause the function to run and assign its value to onclick (just as you were doing when calling addFav(args) )

To make matters worse, I was creating local variables for inside the function by assigning an argList. These need values passed to them in order to work properly... The values could be passed either by using pasedArgList (in which case the function would run automatically) or by calling onclick(args). However web-object events only pass in one argument (if the browser passes anything at all), namely the event (or e). For example, you could write something like:

onmousedown = function(e){
if (!e) var e = window.event; // For IE
var buttonPressed=(e.which) ? e.which : e.button; // IE uses .button property
if(buttonPressed==1) alert("You pressed the left button!");
...which alerts you when you press the left-mouse button (onclick doesn't distinguish this, which is why I made the function for the onmousedown event instead). However, you cannot use the event argument to assign parameters for the addFav() function inside.

However, the anon. function doesn't need to create local variables itself; it just needs to be able to use variables that are in scope. Since you defined myURL and myTitle as global, you can use those variables inside the function body without creating a separate argList... Thus:

el.onclick = function(){
alert("Inside annon. function with\n'"+myURL+"'\nand '"+myTitle+"'");
addFav(myURL, myTitle);

...will work for IE the way you intended (I added the alert() to show you that the variables are being used inside the function body...)

There is still the problem with FF tossing an error:

Error: [Exception... "'Script attempted to add sidebar panel from illegal source' when calling method: [nsISidebar::addPanel]" nsresult: "0x8057001e (NS_ERROR_XPC_JS_THREW_STRING)" location: "JS frame :: file:///D:/Web/wwwroot/test.html :: addFav :: line 21" data: no]
Source File: file:///D:/Web/wwwroot/test.html
Line: 21
(same error if the page is run off of the web instead of directly from the file) Like I said before, this might be because of security issues with Firefox, so you may need to "try...catch"ing the bookmark method and do the alert("Bookmark page yourself") thingy if it doesn't work...

Jules Manson
01-04-2006, 09:15 PM
Dear Pyth007:

Thank you for your thorough reply. I will attempt your solution and let you know if I can get it to work. I also took a second look at your signature today and the last part regarding STFW appeared arrogant and in contradiction to what users of this forum are doing. You see people do first STFW before resorting to a forum. That is how they run into forums in the first place. Secondly, a forum is the web.

01-05-2006, 11:29 AM
why are you creating a silent bookmarking script. surely, if users want to add your site to their favourites list they'll do it for themselves. it isn't up to you to do it for them. also adding another button is redundant because the browser already has one and thus adding one yourself is a waste of time and space.

01-05-2006, 04:09 PM
The STFW may seem somewhat arrogant, but then again, many forum users ask first, search later (myself (http://www.codingforums.com/showthread.php?t=74434) included, sometimes... :o ). It becomes especially annoying when someone asks a simple question where there are oodles of tutorials on the web that would be more instructive. It's just easier to ask a question and be "spoon-fed" the answer than it is to do the hard work yourself and read / search what others have asked. But then again, "no pain, no gain"; when people actually do the searching / reading themselves, they will actually learn more and are provided with more information, whereas forums are more geared more to provide short answers.

For example, let's say a user wants to put a menu-system onto their web-page. Going from laziest to a hard worker: 1) A "cheater" (or someone that wants results with minimal effort) would find a pre-made script somewhere and copy/paste it into their own site. 2) A bad forum user would find some forum, ask someone to create a menu script, and copy/paste it into their site. 3) An average forum user would work together with other forum members to create a menu-system (this could be rated higher depending upon
the amount of involvment of the user in developing the menu-system). 4) The user STFW and finds a menu-system tutorial, completes all of the excersizes, and develops their own replca of the tutorial's system. 5) The "good" forum user gets pretty good at js and develops their own system, asking questions to get other's insite into their code, but at the end of the day, the menu-system is basically their own creation. 6) A person masters the use of js and develops their own system, answering their own questions, etc.

This example is not to say that a type 1) user couldn't learn from the code they took, nor is it to say that type 6) users are the "best" (many professional programmers rely on a network of peers in order to brainstorm new models / ideas; and many professionals ask others to look over their code since some syntax errors are too small to notice (like mistaking 2 single-quotes ('') for a set of double quotes (") ) ). In fact, their probably aren't any real 6's except for those that actually devised the language to begin with. And -- as mentioned in type 3) -- this order may change depending upon the amount of effort the user puts in.

Yet this "spoon-fed" mentality seems to pervade many "intellectual" circles.
My parents were dumbfounded when standing in line at a parent-teacher conferense for my high school. The parents ahead were lamenting how the "bad" teacher was requiring the students to read the chapter before coming into class (the gall of the teacher to assign homework! ;) ) I guess a "good" teacher would just tell the students what circle to fill in on the test.
There were some college courses that where I stopped going to "study sessions" because it would usually revolve around me opening up their pristine textbooks and pointing to the page that answers the question they just asked. At times, I just wanted to scream RTFM (or RTFTB (TB = textbook) as the case may be). If they had actually read the assigned text and did the assigned examples, they probably would have learned more and done better on the tests.
I was even appalled in grad. school when students would ask if something was going to be on the test. Like they wanted to be "spoon-fed" everything needed for the test and nothing else, instead of taking every opportunity to learn all they could from what (presumeably) is going to be their eventual profession.

This rant is not to say that forums don't have their use, nor is it to say that a person needs to be a guru in order to be a "good" forum user. There are times that a person just doesn't know the terminology or concept to get what they want. A forum is the perfect place to describe their problem and have a more knowledgeable person provide that missing piece of info. The questioner should then take that piece of info and STFW in order to get more knowledge on the topic instead of asking a series of incrementally more complex questions on the topic. Like I said at the beginning, forums give short answers (eg "Try searching for regular expression methods") while tutorials on the web do a much better job of giving an in depth answer.

Also there are times that searching for an answer is overly difficult. Certain js keywords are too generic to get a good search: 'this', 'if', 'for', 'case', etc. Or get confused with other concepts in a search engine (eg the window object vs. MS's Windows OS). Or there are too many results to sift through to get an answer you need (especially if there are oodles of tutorials giving basic info. but what you actually are searching for is a more complex / specific piece of info relating to the topic). Search engines (at least the more common ones) basically use the occurance of words in text to find a match, whereas forums rely on the semantics of those words in a question.

To address your specific comments: I somewhat disagree that all forum users already STFW... Some people may find the forum on one search and then continually use the forum for any subsequent question they have instead of searching again for their answers. Others may have been directed to this site by someone else, and so have never searched the web for their problem in the first place. (I even took a class where the professor gave the web address of a different forum as a source to get answers to student's questions; unfortinuately, too many students abused that forum in order to get their homework done for themselves). And yes the forum is a web-site, so that comment is also a reminder to people to use the forum's search button.

Jules Manson
01-05-2006, 04:43 PM
Dear Pyth007 and jbot:

Again I get a very considerate response by Pyth007 and that I really do appreciate. I do not have time to work on the bookmark script today but I will continue on it at a later date and when I do I will post the final solution here and at some other sites. Regarding people who do not thoroughly read my initial posting (request for help) and make comments I have one thing that I should say to them:

RTFP (Read The F%#&'n Post)!

I will now answer jbot's comment:

1. This is not a silent bookmark script.

2. The intention of creating this bookmark is to allow someone to bookmark a page that is framed. And, yes I do provide a "break out of frames" link on there as well however not all users will use that or even know what a frame is so I want the link to bookmark the framed page for them. Please, no rant on why frames "suck." Frames "suck" only when people do not implement them correctly or implement them for the wrong reasons. Trust me when I say that I have very valid reasons (yes plural) for using frames on a particular site that I am building.

3. This script will serve as a model for creating other similar unobtrusive scripts where other window objects are called. Please see the links on my signature before asking why I want to remove inline-event handlers from my HTML or asking what "unobtrusive scripting" is.

Whewww! I hope people RTFP before commenting on this again. ;)

01-05-2006, 05:12 PM
so, what if the user doesn't have JS or a frameset-compatible browser? *just curious*

trust me when I say that I have very valid reasons (yes plural) for using frames on a particular site that I am building

you can do the same using CSS now, you know. much slicker and degrades nicely for users of non-frameset browsers. :thumbsup:

Jules Manson
01-05-2006, 08:20 PM
Dear jbot:

I feel like you're pulling my rooster now. There is no need for that. However I will assume that you are a novice at web design (not to be confused with a novice at scripting) and your questions are sincere. Anyone who has a computer system so antiquated that they do not use browsers that support frames are probably still crawling on Netscape 1.0 or Internet Explorer 1.5 with Windows 95. These people are cheap or in oppressive third world nations or in prison. I have no interest in catering to them and neither should you. As for people who have javascript turned off I use accessible scripting which degrades gracefully and still allows one to open my pages without the need for javascript. CSS is a newer technology than browsers which support frames. This means that it is far more likely for browsers to support frames than it is for them to support CSS. As for using CSS to replace frames I had no idea that CSS could embed another web page inside another page or frameset. If this is now possible please show me how or post a link here so that I can see how this is done. If it is new in CSS3 then most if not all browsers do not support that. If you mean XSL not all browsers support XSL and I do not have time to discuss XML, XSL, or how it is up to a server to parse XML/XSL content before serving it to a client as HTML/CSS. My only interest is getting my unobtrusive script to work.

I have two things to say to people who do not contribute anything useful and instead ask questions which have nothing to do with the topic:

STTFT (Stick To The F%#&'n Topic)!

There is no such thing as a stupid question. Only snaggletoothed redneck simpletons from the south who marry their sister while living in double-wide trailers and smoke crack all day. :thumbsup:

01-06-2006, 10:03 AM
I will assume that you are a novice at web design (not to be confused with a novice at scripting) and your questions are sincere.

nope, got 6 years pro experience and 4 years as an amateur. you're still better going with a CSS layout than a frames-based one. but i'm bored already and won't argue the toss with you: do what thou wilt. i'm really not bothered.:cool:

Jules Manson
01-06-2006, 04:05 PM
Dear jbot:

I am sure you are better at creating professional web sites with CSS frames than this amateur (smirks).

01-06-2006, 04:13 PM
I am sure you are better at creating professional web sites with CSS frames than this amateur

LOL ... I never said it was straightforward. but for me it is preferrable, especially in this instance since you don't have to create complicate scripts to mimic what the browser can generally handle for you. (smirks)