ha, ha. I figured it out finally, and of course it's obvious when you look at it and has nothing to do with what I thought it did.
Here's the thing: the form (or whatever it is) gets submitted via the click on the button. So adding another click listener puts that second listener at the end of the queue, and the function fires too late (I don't know how this fits in with LIFO, or maybe I just don't understand LIFO).
But of course using mousedown means you get to sneak in before the click function fires and do your validation routine.
Thanks for sticking with me, though, rnd me. It was an interesting discussion regardless.