I ran into a rabid Safari error for iPad that I cannot fix.
Architecture:
- trunk 0.9.9
- jquery 1.7.2
- jquery mobile 1.3.1
User Agent:
- iOS 5.1.1 (iPad)
- Safari 5.1 mobile
- full user agent string: Mozilla / 5.0 (iPad, CUP OS 5_1_1, like Mac OS X) AppleWebKit / 534.46 (KHTML, e.g. Gecko) Version /5.1 Mobile / 9B206 Safari / 7534.48.3
I have 10 instances of the same view, each of which has a nested view containing a textarea element. For some reason, when you click on a text field, it does not randomly focus. I read that Safari mobile is elusive when you try to trigger focus events that don't come from a click / click event, but this is a direct answer and it still doesn't focus reliably. Here's a stripped down code for views:
var ParentView = Backbone.View.extend({ render: function() { this.$el.html("<div class='textarea-container'></div>"); this.textareaView = new TextareaView({ el: this.$el.find('.textarea-container') }); this.textareaView.render(); } }; var TextareaView = Backbone.View.extend({ events: { 'tap .my-textarea': 'handleTextareaTap' }, render: function() { this.$el.html('<textarea rows="4" cols="80" class='my-textarea'></textarea>'); }, handleTextareaTap: function(event) { console.log('TAPPED'); } }; var i = 0; while ( i < 10 ) { var view = new ParentView(); view.render(); $(body).append(view.$el); i++; }
The crane event handler fires for 100% of the time. The console correctly displays "TAPPED" every time. But most of the time, the user agent does not focus on the text field. I added the following line to TextareaView to see which Safari events are fired and in what order:
var TextareaView = Backbone.View.extend({ render: function() { this.$el.html('<textarea rows="4" cols="80" class='my-textarea'></textarea>'); this.$el.find('.my-textarea').on('blur change click contextmenu copy cut dblclick focus focusin focusout hashchange keydown keypress keyup load mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup mousewheel paste reset scroll select submit textinput unload wheel tap touch scrollstart scrollstop swipe swipeleft swiperight vclick vmousecancel vmousedown vmousemove vmouseout vmouseover vmouseup touchstart touchend touchmove touchcancel', function(event) { console.log(event.type); } }, };
Here is the order of events that I get when textarea focuses correctly: touchstart, vmouseover, vmousedown, touchhend, vmouseup, vclick, tap, vmouseout, mousemove, mousedown, focusin, focus, mouseup, click, focusout, blur
Here is the order of events that I get when the text field cannot focus: touchstart, vmouseover, vmousedown, touchhend, vmouseup, vclick, tap, vmouseout, mousemove
For some reason, events after mousemove do not fire. I also tried manually triggering these events, but the textarea element still does not focus and the keyboard does not appear, for example:
var TextareaView = Backbone.View.extend({ handleTextareaTap: function(event) { // This still doesn't work: this.$el.find('.my-textarea').trigger('focus'); // Neither does waiting for the synthesized WebKit events to fire: var _this = this; setTimeout(function(){ _this.$el.find('.my-textarea').trigger('focus'); }, 1000); } };
I posted the Apple event handler documentation over to no avail, and I cannot find any error messages related to this in any of the github repositories.
Two other weird behaviors that I don't understand:
- the first instance of textarea always works correctly
- textarea focuses even though the blur event is called
Any insight would be appreciated.
Greetings