Even with these answers it took me three days to figure out what was going on and I may need the solution again in the future.
My situation was slightly different from the one described.
In mine, I had some contenteditable text in a div on the page. When the user clicked on a DIFFERENT div, a button of sorts, I automatically selected some text in the contenteditable div (a selection range that had previously been saved and cleared), ran a rich text execCommand on that selection, and cleared it again.
This enabled me to invisibly change text colors based on user interactions with color divs elsewhere on the page, while keeping the selection normally hidden to let them see the colors in the proper context.
Well, on iPad's Safari, clicking the color div resulted in the on-screen keyboard coming up, and nothing I did would prevent it.
I finally figured out how the iPad's doing this.
It listens for a touchstart and touchend sequence that triggers a selection of editable text.
When that combination happens, it shows the on-screen keyboard.
Actually, it does a dolly zoom where it expands the underlying page while zooming in on the editable text. It took me a day just to understand what I was seeing.
So the solution I used was to intercept both touchstart and touchend on those particular color divs. In both handlers I stop propagation and bubbling and return false. But in the touchend event I trigger the same behavior that click triggered.
So, before, Safari was triggering what I think was "touchstart", "mousedown", "touchend", "mouseup", "click", and because of my code, a text selection, in that order.
The new sequence because of the intercepts is simply the text selection. Everything else gets intercepted before Safari can process it and do its keyboard stuff. The touchstart and touchend intercepts prevent the mouse events from triggering as well, and in context this is totally fine.
I don't know an easier way to describe this but I think it's important to have it here because I found this thread within an hour of first encountering the issue.
I'm 98% sure the same fix will work with input boxes and anything else. Intercept the touch events and process them separately without letting them propagate or bubble, and consider doing any selections after a tiny timeout just to make sure Safari doesn't recognize the sequence as the keyboard trigger.