The best way to FRAME-proof your pages, boost table speed, & more2 free Perl scripts that add HEIGHT & WIDTH to IMG tags automaticallyBy Chuck Musciano |
has become May 1997 |
|
Summary Never say never, especially on the net. It's a lesson I learned long ago while inciting flame wars in various news groups. A lesson I promptly forgot when putting together my March column. I foolishly claimed that it was impossible to keep your pages from being loaded within someone else's frames, inciting dozens of people to point out exactly how wrong I was. I'll offer a weak defense and then share their tricks, along with some page performance tuning tips, a nifty image handling tool, and one last image-width hack. (1,700 words) |
|
|
To recap, a reader wrote complaining that their beautiful pages
were being referenced from within frames on other sites. On those
sites, the link to their site did not contain a target=_top
attribute, causing their pages to be squeezed into a frame within the
linking page. The result was ugly and bothersome, especially since the
reader's pages were being diminished by someone else's HTML
shortcomings. How could he keep this from happening?
The answer lies not in HTML, but in JavaScript. It only takes a few lines of JavaScript to detect the presence of frames and to then remove them.
I was struck by how many different ways authors had come up with to detect that frames were being used on the current page. All of the following JavaScript conditional expressions will test to see if frames are in use:
if (self.location != top.location)if (self != top)if (top.frames.length > 0)length member keeps a
count of how many frames are currently defined. If that count is
greater than zero, frames are being used. It is also possible (and more
elegant) to write this condition simply as
top.frame.length. Since any non-zero value in JavaScript
(like C) is equal to "true", a non-zero frame count returns a true value
as well.
if (top.frames[0].name != "name")0 in the condition with the number of a
suitable named frame in your document, and replace the
"name" with the name of the frame. If the names don't
match, your frames have been captured within another set of frames.
Once you detect that they are in use, breaking free is easy. Simply set
top.location to your document's URL. When this property is
changed, the browser will reload the document into the top-level browser
display, removing all the frames and replacing them with your document.
Readers were split in setting top.location, relying on two
principal methods:
top.location = "URL";
top.location = self.location;
The last piece to the puzzle is adding this snippet of code to your
documents. We put this down with the onLoad attribute of the
<BODY> tag. The JavaScript fragment assigned to this
attribute is executed as the page is initially loaded by the browser.
This means that the page can detect the presence of frames almost
immediately, before your page is fully presented to the user. Since a
change to the top.location property results in an immediate
reload, you'll break free of the frames almost instantly.
Collecting all my favorite pieces of the puzzle, I offer this version of
the <body> tag to frame-proof your pages:
<body onLoad="if (self != top) top.location = self.location">
Most modern browsers are designed to show as much content as possible to the user as quickly as possible. This means that as soon as the browser can render the content of the visible portion of the page, it will do so, downloading the remainder of the page as you read the first portion.
The browser cannot lay out a page until the sizes of all the objects in
the page are known. This means that the browser needs to know the sizes
of all the images in the page, and the sizes of all the tables. Images
are easy: just add the height and width
attributes to each <img> tag in your page. The
browser will use those sizes to allocate space for the image, instead of
downloading the image to determine its size.
Tables are more of a problem. The browser must scan the entire table to
determine how many columns are in the table, and then must render each
cell in the table to see how wide each column must be. You can help
this process a bit by adding the cols attribute to the
<table> tag, telling the browser how many columns you
intend to create. Sizing the table cells is harder to make faster,
since the browser must read the entire table before making any
decisions. If your page consists of one giant table for layout control
purposes, it may take a long time for the browser to display just the
first portion of your document.
Hal's suggestion is to split your table into two pieces: a smaller table that loads quickly and fills the first visible portion of your document, and the larger remaining portion which can be loaded while the user reads the first section. This suggestion keys on the psychological aspects of interface design: the perception of speed is almost entirely subjective. Huge pages that manage to present a small amount of content early in the loading process will "feel" faster than a smaller page that must fully load before it can be displayed.
<img> tag on your page is
tedious and error-prone. I'm also adamant that you use them wherever
possible to reduce page rendering time. Finally, I hate spending a lot
of time tweaking my <img> tags every time I change an
image.
Fortunately, a kind reader pointed me to
gifsize,
a nifty tool that reads your HTML documents, finds all the
<img> tags, locates the referenced image, and inserts
the appropriate height and width attributes
back into the <img> tag. What more could you want?
Gifsize is a Perl program that should run on any computer sporting Perl. It has a few options you'll need to set before running it the first time, but even inexperienced users should have gifsize doing something productive in short order. Gifsize is perfect for processing documents that use images stored directly on your system.
If you find gifsize hard to use or lacking in some way, try WWWis instead. Based upon gifsize, WWWis fixes many of the shortcomings of gifsize and goes on to offer several other nice features, including the ability to download images from another server. Again, you'll need the ability to run Perl on your computer, and WWWis has even more user-level options than gifsize. Still, the net result is worth a bit of your time to configure the tool, and visitors to your site will be eternally grateful for your snappier page loading times.
width=100% to your <img> tags. This
little trick worked great, except that several readers discovered that
it did not work when the image was contained in some other HTML
container, especially a table cell. In these cases the browser just
ignored the image.
By sheer chance, a reader happened to discover that percentage image widths do work in table cells if the cell happens to contain a horizontal rule. Even better, the rule need not be in the same cell; placing it in another cell in the same column seems to work just as well. Clearly, this is a browser bug, but if you simply must have images stretch to fill a table cell, and you can tolerate a horizontal rule somewhere in the same column, this little trick might just save the day.
|
About the author
Chuck Musciano has been running Melmac and the
HTML Guru Home Page
since early 1994, serving
up HTML tips and tricks to hundreds of thousands of visitors each month.
He's been a beta-tester and contributor to the NCSA httpd
project and speaks regularly on the Internet, World Wide Web, and related
topics. His book,
HTML: The Definitive
Guide, is currently available from
O'Reilly and Associates.
Reach him at
chuck.musciano@netscapeworld.com.
You can learn more about and buy
HTML: The Definitive Guide (Second edition) at Amazon.com Books.