Whether or not you think that pop-ups are a modern form of
pestilence, like locusts and Britney Spears CDs, there are times when they are
a necessary evil. Many Web-based applications use pop-ups for a number of
mundane tasks ranging from displaying help pages to displaying different images
of available products. Unfortunately, if the client’s browser has a pop-up
blocker installed and enabled then you’re pretty much out of luck when it comes
to using pop-ups.
One possible solution is to have messages throughout your
site saying something like, “This site utilizes pop-up windows. Please ensure
that your pop-up blocker is disabled for this site.” But that’s not very
user-friendly to make someone deactivate the blocker just to use your site.
What’s needed instead is a way to tell if a user has a pop-up block so that your
site can then tailor the browsing experience.
Use a pop-up to kill a pop-up
The method that I’ve chosen to accomplish this task is by
trying to open a pop-up window. Of course, this means that I have to be rather
defensive in my programming because if I’m not, the possibility exists for the
client seeing an error. With this in mind, I installed the Google Toolbar and began to
code a page with an onload event handler that checks for pop-up blocking
software. The results of this endeavor are shown in Listing A and Listing B.
The way that the page shown in Listing A works is that the
onload event handler, setEvents, is fired and it attempts to open the page
popupChild.html shown in Listing B. While it may seem that an error trap is
enough to determine if the pop-up worked, that isn’t always the case. Depending
on the pop-up blocker installed there may or may not be an error. What’s needed
is essentially for the child window to stand up and say, “Hello, world!”
or something along those lines. The page then uses the setTimeout method to
delay the invocation of the function checkChild; this gives the pop-up the time
needed to alter a hidden input object on the parent window and close itself.
Once this has been accomplished, the function checkChild checks the value of the
hidden input object to determine if the child window modified its contents. If
the contents have changed, then the pop-up worked, which means no pop-up
The two hardest parts of this entire testing process are accessing
the hidden input object on the parent window and estimating how long it should take
for the pop-up to open. The first problem is easily solved through the use of
the Document Object Model’s window.opener property. The second part is a lot
harder; after all, as I play around with these examples the browser and the server
are on the same machine. So while these examples worked for me, they might not
work for everyone everywhere. There has to be a better way.
A better way
regardless of the browser, it is relatively consistent. If something works on
one browser, the odds are that only a little tweak will be necessary to get it
to work on another. For example, coding an alert with an
object results in “[object]” in Microsoft Internet Explorer and “[object
Window]” in Mozilla. Another interesting thing is that the
aforementioned only happens when the object is actually created. The result of
this line of reasoning is shown in
Listing C. Note that because we’re only checking to determine if a pop-up can be
opened, it’s merely an empty page.
One of the reasons that I developed this code is because,
recently, several developers and technical support people spent three hours in
a conference room dealing with this issue on our order entry system. A remote
client insisted that they didn’t have a pop-up blocker; only after having
exhausted all possible problems on our end did someone suggest reviewing the
client’s installed programs. Near the bottom of that list was a program that
added cute little smiles to the client’s e-mails. After a little research it
was determined that not only did it add smiles to e-mail, but among other
things, it also blocked pop-ups. The user had installed a pop-up blocker and
didn’t even realize it, which is the problem that I’m trying to avoid in the
future with this code.