Additional parameters within preventDefault() for more control on what gets prevented

360 views
Skip to first unread message

Adam Bradley

unread,
Apr 29, 2014, 1:03:34 PM4/29/14
to chromium...@chromium.org

I've been working on a mobile app that involves removing the 300ms delay on mobile, focusing on inputs, and bringing up the virtual keyboard (this post isn't about looking for a solution like fastclick or using touch-event, but specifically about preventDefault). A lot of the issues I'm having could be solved if I was able to be explicit on what "prevent default" means.


The preventDefault spec says:

"...any default action normally taken by the implementation as a result of the event will not occur."

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-preventDefault


The problem is that browsers seem to have a different meaning of what the defaults are, and lumps all of these different types of defaults into one. You can’t prevent one or two of the defaults, you either always do or always do not prevent all of the defaults.


For example, I need disable scrolling when a textarea is focused, so to do this I can set e.preventDefault() on touchstart. However, if I preventDefault on touchstart then the virtual keyboard does not show in Android (it does show on iOS).


This isn't surprising the keyboard doesn't show in Android when e.preventDefault() is called within touchstart, but because both native scrolling and bringing up the virtual keyboard are part of the event defaults for a textarea, I'm not able to specify exactly what should happen. Other related defaults that can get prevented include being able to move the text caret within a textarea, suggested words, setting focus, etc.


So with preventDefault actually meaning to prevent every default that can happen from this event on a target, what if additional parameters could be added to allow developers to be more explicit of what should be prevented. This is far from standards ready and isn’t the proposal, but the code below is an example of how it could work:


e.preventDefault({ scroll: true });


or


e.preventDefault({ keyboard: true, textCaret: true });


So the first example would only prevent the scroll from happening, and the second example would prevent the keyboard from showing or a text cursor from showing. Every target and event has different defaults that happen, and each browser it seems has different ideas on what those defaults are, but this would allow devs to control which ones get prevented instead of all of them. I'm just looking to open a discussion on whether this would be useful and/or possible. Thanks.

Rick Byers

unread,
Apr 30, 2014, 11:19:17 AM4/30/14
to ad...@drifty.com, Chromium-discuss, public-to...@w3.org, zees...@chromium.org, input-dev
+public-touchevents community group and input-dev chromium list

Hi Adam,
I agree that preventDefault is overloaded to control way to many things.  The problems I'm aware of typically do have some solution, but they're often non-obvious (and there's probably issues I'm not aware of, especially when you consider multiple browsers).  Eg. for your scenario of disabling scrolling without disabling actions that happen as a result of a 'tap' (like bringing up the keyboard or moving the caret) I _think_ you want to be careful to call preventDefault ONLY on touchmove events.  Can you try that and tell us if there are other scenarios that still aren't addressed?

Regardless this is too difficult and confusing, especially since the behavior of preventDefault isn't precisely specified (because it was too late to get the various implementations to agree).  To help combat this I've pushed the standardization and adoption of the 'touch-action' CSS property: https://dvcs.w3.org/hg/pointerevents/raw-file/tip/pointerEvents.html#the-touch-action-css-property.  For your case you probably want to mark your text area (or whatever) 'touch-action: none' to disable scrolling/zooming without disabling all the other behaviors. We're shipping support for this in Chrome-35 (https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/sc5lHnlcLvM), IE11 has support, and support is coming to Firefox soon (no word about Safari unfortunately).  Does this help?

If there are additional things we should give precise control over, I personally believe we should probably do that with new APIs rather than overload the already incredibly complex preventDefault method.  For example, we (zeeshanq@ in particular) are starting to explore ideas for a new API to give you control over exactly when the virtual keyboard comes up.  I'd love to hear details of any use cases you have here (we're not sure, for example, if this should be a CSS property, a new JavaScript API, or some parameter on the focus() API).
 
Can you describe any other scenarios for which you'd need separate control?  I'm hesitant to say we just should dump every UI detail into some enable/disable API as it could overly constrain the UI and make the platform hard to evolve.  But if we can come up with specific scenarios that can't be solved without some API (especially when such an API exists on other platforms) then that's a strong case.

I hope this helps,
  Rick


--
--
Chromium Discussion mailing list: chromium...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-discuss


Adam Bradley

unread,
Apr 30, 2014, 12:54:58 PM4/30/14
to chromium...@chromium.org, ad...@drifty.com, public-to...@w3.org, zees...@chromium.org, input-dev
This all stems from developing ionicframework.com, and finding that balance when having the ability to scroll an element with touch/mouse events, bringing up the virtual keyboard, moving the input's text caret, removing the 300ms delay, setting an "active" css class on buttons, etc. Most of our code could be simplified if preventDefault wasn't preventing everything from happening, along with the problems of it acting differently on Android and iOS. The end goal is to be able to control what defaults get prevented, so if newer APIs would be the better route then I'd be all for it.

A virtual keyboard API would also solve many of these issues. Currently it's pretty difficult to bring up the keyboard with just focus() because it needs to come from a user interaction like touchstart (but from what I understand this is by design). Other valuable information would be the keyboard height, it's layout type (like iOS split keyboard), removing the "Next" and "Done" accessory buttons if you wanted, adding your own accessory buttons, customizing the "Enter" button text (like to Search, Go, Filter), events triggered on keyboard show, hide and word suggestions, and possibly having some more control of the keyboard's actual keypad layout. When comparing native mobile app development to html5, these are some of the areas that could help web and hybrid app developers further.

Thanks,
Adam

Rick Byers

unread,
Apr 30, 2014, 1:10:16 PM4/30/14
to Adam Bradley, Chromium-discuss, public-to...@w3.org, zees...@chromium.org, input-dev, Tom Wiltzius, David Bokan
On Wed, Apr 30, 2014 at 12:54 PM, Adam Bradley <ad...@drifty.com> wrote:
This all stems from developing ionicframework.com, and finding that balance when having the ability to scroll an element with touch/mouse events, bringing up the virtual keyboard, moving the input's text caret, removing the 300ms delay, setting an "active" css class on buttons, etc. Most of our code could be simplified if preventDefault wasn't preventing everything from happening, along with the problems of it acting differently on Android and iOS. The end goal is to be able to control what defaults get prevented, so if newer APIs would be the better route then I'd be all for it.

Understood.  So does touch-action help you here (in that it lets you control scrolling and zooming without affecting other things)?  Note that one potential disadvantage to touch-action is that you can't have it affect a touch sequence once it's already started (i.e. change it in response to a touchstart).  This is intentional because it enables optimizations that apply touch-action without blocking on JavaScript at all, but it means it's not quite as rich as a JS-API based approach like you were suggesting.  For most cases though this seems like the right design choice.

A virtual keyboard API would also solve many of these issues. Currently it's pretty difficult to bring up the keyboard with just focus() because it needs to come from a user interaction like touchstart (but from what I understand this is by design). Other valuable information would be the keyboard height, it's layout type (like iOS split keyboard), removing the "Next" and "Done" accessory buttons if you wanted, adding your own accessory buttons, customizing the "Enter" button text (like to Search, Go, Filter), events triggered on keyboard show, hide and word suggestions, and possibly having some more control of the keyboard's actual keypad layout. When comparing native mobile app development to html5, these are some of the areas that could help web and hybrid app developers further.

Thanks for the feedback, these all sound like important problems to solve.  +wiltzius and bokan who are also looking at some related issues (eg. how/when to tell you what part of the viewport is occupied by a keyboard).  Making it possible to do everything you'd want in a native Android/iOS app using standard web APIs is a big priority for the blink team right now - there's just a lot of ground to cover (and standards work is slow), so we're trying hard to prioritize effectively.   


Thanks,
Adam

Reply all
Reply to author
Forward
0 new messages