views:

1026

answers:

4

I am implementing a shopping cart for my website, using a pseudo-AJAX Lightbox-esque effect. (It doesn't actually call the server between requests -- everything is just Prototype magic to update the displayed values.)

There is also semi-graceful fallback behavior for users without Javascript: if they click add to cart they get taken to an (offsite, less-desirable-interaction) cart.

However, a user with Javascript enabled who loads the page and then immediately hits add to cart gets whisked away from the page, too. I'd like to have the Javascript just delay them for a while, then execute the show cart behavior once it is ready. In the alternative, just totally ignoring clicks before the Javascript is ready is probably viable too.

Any suggestions?

+1  A: 

Is your code really that slow that this is an issue? I'd be willing to bet that no one is going to be buying your product that soon after loading the page. In any reasonable case, the user will wait for the page to load before interacting with it, especially for something like a purchase.

But to answer your original question, you can disable the links in normal code, then reenable them using a document.observe("dom:loaded", function() { ... }) call.

Ben Alpert
if he disables the links and the user doesn't have javascript enable will his failsafe still work?
bendewey
Well, depends how you disable them. If you have a short JavaScript snippet that doesn't depend on anything else being loaded, you can run that easily even before the page is completely ready.
Ben Alpert
Like at the end of the page, because otherwise the elements wouldn't be there yet. right?
bendewey
A: 

You can try, hiding the links in css then show them when the page loads.

<script type="text/javascript">
  document.write('<link rel="stylesheet" type="text/css" href="someCssThatHidesLinks.css" />');

  window.onLoad = function() {
    //show links
  }

</script>

This way, if your user doesn't have javascript, then their links are still active, otherwise if they do, then the links are hidden until you load and activate them. Never done this before, but i think this should work if you want to retain the features of your failsafe page.

bendewey
Disabling in CSS? How would you do that?
strager
Only by making them completely disappear, I think—not a good idea.
bobince
don't know what i was thinking
bendewey
A: 

However, a user with Javascript enabled who loads the page and then immediately hits add to cart gets whisked away from the page, too.

When are you starting up your scripts? If you're using document onload, it will be waiting for all the images to download before initialising, which would indeed give the user a chance to click-to-buy.

If you trigger the JS enhancement when the DOM is ready, either by just putting your <script> at the bottom of the page, or by using a DOMContentLoaded-style event supplied by your framework, the links should adapt fast enough that the user is very unlikely to be clicking the button first.

If you really, really want to delay clicks that are placed between the element first being parsed, and the document being loaded, you could write something like:

<script>
    function methodcall(obj, name) {
        return function() {
            obj[name].call(obj);
        };
    }
</script>
...
<a href="nonjsversion" onclick="setTimeout(methodcall(this, 'click'), 500); return false;">Buy</a>
...

So that it'd just spin there polling (and, on IE, leaking memory) until the link's real click handler was in place. It's pretty ugly though, and fragile in that if your script breaks for some reason (and it's JavaScript, so it's pretty likely that at some point, on some browser, it will), your button will break. This problem applies to all potential solutions that rely on a later-running JavaScript enabling previously-disabled actions.

And there's nothing worse for business than a broken buy button.

bobince
+3  A: 

I now do this with jQuery b/c I vaguely recall browser differences which jQuery takes care of:

Try

$(document).ready(function() { // put all your jQuery goodness in here. });

Pita.O