Full Page History:

Oldest known version of this page was edited on 2005-10-08 14:25:16 by Jakub81 [fuck fuck fuck]

Page view:

Making Bookmarklets Frames Compatible

BookMarklets are short pieces of javascript that run code on the current web page. Unfortunately many of them are not compatible with pages that use frames. Normally this is to keep the length of the script down (Internet Explorer in particular can have some very restrictive limits). But since this is a page for Opera users, and since Opera has the longest limit of any browser (AFAIK), this is an an attempt to impart my wisdom on the world.
BookMarklets will remain compatible with pages that don't use frames.

Pretty much all the code here has been figured out from looking at other people's BookMarklets (see that page for more links)
It's quite possible there are some things I do that I don't fully understand... And which may cause problems later, feel free to correct me.

Step 1. Find your bookmarklet

For this simple example I will use the following Bookmarklet that 'fixes' any marquees on a page

javascript:var m=document.getElementsByTagName("marquee");for(var i=0;i<m.length;i++) m[i].style.display="table-row";return false;

Step 2. Formatting

Now that you have your script, it's time to format it... Trust me, this will help lots with the longer scripts.
I have also added comments, mostly for tracking benefit, they will be removed again before the end.

javascript:
  var m=document.getElementsByTagName("marquee"); // make m an array of all marquees
  for(var i=0;i<m.length;i++) // loop through the marquees
	m[i].style.display="table-row"; // edit the style so that opera kills the animation
  return false; // standard bookmarklet closer

As a bonus I will enclose the code in an anonymous function... this gives the benefit of allowing any variable name to be used without interfering with page variables. You can also drop the "return false;" line.

javascript:(
function(){
  var m=document.getElementsByTagName("marquee");
  for(var i=0;i<m.length;i++)
	m[i].style.display="table-row";
})();

Detour: The Frames Template Code

You shouldn't need to read this bit after a while, but here is the fully commented template code that your existing script will be wedged into.

javascript:(
function(){   // Note again, anonymous function  

  // *************************************
  // Insert the main code of the script here in a function
  // The function name can be whatever you choose
  // The script must also accept at least one parameter
  // This will represent a document object
  // *************************************

  // declare any script wide variables
  var f=window.frames; // get the frames

  if(f.length==0){ // If the page has no frames
	// run the function on the "document" object
  }
  else{ // page uses frames
	// You may still want to run the code on the top level page here
	// I.E. the page with <Frame set> etc....
	for(var i=0;i<f.length;i++){ //loop through each frame
	  // run the function on the "document" object of the current frame
	}
  }
  // place here any code to be done
  // If, for example the script was counting links.. here would be the place to put the alert()
}
)()

Step 3. Porting the code

If we look at the last version of the current code.

javascript:(
function(){
  var m=document.getElementsByTagName("marquee");
  for(var i=0;i<m.length;i++)
	m[i].style.display="table-row";
})();

We can see that in this simple example all the code should be run on each page in the frame set.
So lets make a function out of that code

function killM(d){
  var m=d.getElementsByTagName("marquee"); // notice we are now referring to the passed document
  for(var i=0;i<m.length;i++)
	m[i].style.display="table-row";
  // no need for a return value here.. but they can be used
}

Now we place that into the template... and add the code to run our now named function.
(Remember, because of the surrounding anonymous function we can use sensible names :) )

javascript:(
function(){
  function killM(d){
	var m=d.getElementsByTagName("marquee");
	for(var i=0;i<m.length;i++)
	  m[i].style.display="table-row";
  }
  var f=window.frames;
  if(f.length==0){
	killM(document);
  }
  else{
	for(var i=0;i<f.length;i++){
	  killM(f[i].document);
	}
  }
}
)()

Step 4. Tidying Up

Now that we have our code it's simply a matter of removing any unnecessary whitespace so that it looks more like a real bookmarklet.

javascript:(function(){function killM(d){var m=d.getElementsByTagName("marquee");for(var i=0;i<m.length;i++)m[i].style.display="table-row";}var f=window.frames;if(f.length==0){killM(document);}else{for(var i=0;i<f.length;i++){killM(f[i].document);}}})()

And now we have code that should work on a page with frames.

Caveats

Categories:

CategoryTutorial

Back Links: