Mobile Web - Disable long-touch/taphold text selection - android

I've seen/heard all about disabling text selection with the variations of user-select, but none of those are working for the problem I'm having. On Android (and I presume on iPhone), if you tap-and-hold on text, it highlights it and brings up little flags to drag and select text. I need to disable those (see image):
I've tried -webkit-touch-callout to no avail, and even tried things like $('body').on('select',function(e){e.preventDefault();return;}); to no avail. And the cheap tricks like ::selection:rgba(0,0,0,0); won't work either, as hiding these won't help - selection still happens and it disrupts the UI. Plus I'm guessing those flags would still be there.
Any thoughts would be great. Thanks!

-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
-webkit-tap-highlight-color:rgba(0,0,0,0);
This will disable it for every browser going.

Reference:
jsFiddle Demo with Plugin
The above jsFiddle Demo I made uses a Plugin to allow you to prevent any block of text from being selected in Android or iOS devices (along with desktop browsers too).
It's easy to use and here is the sample markup once the jQuery plugin is installed.
Sample HTML:
<p class="notSelectable">This text is not selectable</p>
<p> This text is selectable</p>
Sample jQuery:
$(document).ready(function(){
$('.notSelectable').disableSelection();
});
Plugin code:
$.fn.extend({
disableSelection: function() {
this.each(function() {
this.onselectstart = function() {
return false;
};
this.unselectable = "on";
$(this).css('-moz-user-select', 'none');
$(this).css('-webkit-user-select', 'none');
});
return this;
}
});
Per your message comment: I still need to be able to trigger events (notably, touchstart, touchmove, and touchend) on the elements.
I would simply would use a wrapper that is not affected by this plugin, yet it's text-contents are protected using this plugin.
To allow interaction with a link in a block of text, you can use span tags for all but the link and add class name .notSelected for those span tags only, thus preserving selection and interaction of the anchors link.
Status Update: This updated jsFiddle confirms you concern that perhaps other functions may not work when text-selection is disabled. Shown in this updated jsFiddle is jQuery Click Event listener that will fire a Browser Alert for when the Bold Text is clicked on, even if that Bold Text is not text-selectable.

-webkit-user-select:none; wasn't supported on Android until 4.1 (sorry).

Related

Android Knockout Select Problems - Chrome and Native Browser

I'm having separate but related issues relating to dropdown events in both the native and chrome browser on an android device (Samsung Galaxy Tab4).
Chrome - when selecting an item in a dropdown, the change event is fired EVERY time but the UI value doesn't update until focus is changed
Native Browser - The first time a select is changed, everything works fine. All subsequent interactions with select is as follows
--- First time an option is selected, change event DOES NOT fire and value does not update on UI
--- Second time an option is selected, change event does fire, value updates on UI
I'm using knockout with Ajax calls to fill the dropdown list. Here's the template code html (on change event here is just an alert for testing change event):
<div class="col-xs-5 col-sm-5 col-md-2 col-lg-2 search-form-label" data-bind="visibleFade: advancedSearch">
Proceeding Type
</div>
<div class="col-xs-7 col-sm-7 col-md-4 col-lg-4 search-form-data" data-bind="visibleFade: advancedSearch">
<select class="select-12" data-bind="disabled: !proceedingTypeCodes.loaded(), event: {change: onSelectChange}, value: ProceedingType, options: proceedingTypeCodes, optionsText: 'Name', optionsValue: 'Code', optionsCaption: '-- ALL --'"></select>
</div>
The view model is actually built up based on a model brought back from an Ajax call (using the json, it creates the model and binds to self. Values are brought back based on ajax requests, added to select list and loaded is marked as true. This is all called on page load
_dataService.getRemoteSiteData("Case/GetCaseStatusCodes?isForSomething=false", null, _loadCaseStatusCodes);
var _loadProceedingTypeCodes = function (data) {
_viewModel.buildModel({ proceedingTypeCodes: data }, _self);
_self.proceedingTypeCodes.loaded(true);
};
It's worth mentioning that all of this works for all other browsers, devices and platforms. We even have another site that uses this exact same paradigm for building select lists which works great (although there is only one select list on that search page whereas there are multiple ones on this page).
Anyone run into this problem?
I believe this problem is unique to Android's native browser and even when I stripped away knockout, bootstrap, etc, there was still some inconsistency.
What seems to be working is using jquery 'on' and $(this).focus methods to guarantee what you click on is in focus
$('.container').on('click','select',function(){
$(this).focus();
});
I used on as this call is in my _layout page so these inputs won't be on the page when it loads (generally) but it can really go anywhere. Very annoying bug but I think this is a decent workaround.
Related to the chrome issue, this was fixed in Chrome 40.* release

Inconsistent Behavior for Touch Events on PhoneGap

I searched for weeks for a slide plugin that would work on a Phonegap app using knockout, bootstrap and jQuery. Unfortunately, nothing was fitting my needs. So, I built a custom slider. It seems to be working (I'm currently testing it on Android 2.3.4 - I'm starting with the lowest version we plan to support), but it doesn't always respond. The touchstart event seems to be rather sensitive. Does anyone have any ideas on how I can make the user experience more consistent and reactive to the touchstart event? I have researched on this for a few days, and it seems others have similar issues, but nothing exactly like mine. And none of the issues seem to have a definitive answer. Does Phonegap have issues with touch events?
Here is my knockout function:
performSlide: function() {
$('#sliderDiv').on({ 'touchstart' : function() {
$('div.slideArrow').animate({
left: "+=200"
}, 1000, function() {
shell.navigate('home', 'slide');
});
}
});
}
I'm using the event binder on a div to call the function.
<div class="linkHeader" id="sliderDiv" data-bind="event: { touchstart: performSlide }">
I have also ensured that the z-index of my div is set higher than the other elements. The position attribute is also set to relative.
Any advice offered would be much appreciated. I would love if this performed a little better... ok, a lot better. :-)
I have not received an answer, but I ended up figuring out what I needed to change. First, I needed to detect my event and capture it in a variable. Then, I also changed the databinding and .on function to detect the touchmove instead of the touchstart. It is working much better now.

jQuery.mobile popup immediately hides after showing

I have a small phonegap application with jquery mobile and backbone.
I'm trying to show popup to user by manually calling .popup() method.
Everything works fine on iOS but on android I got strange issue: popup is showing for few moments and than disappear.
Here the actual code:
var PostView = Backbone.View.extend({
events: {
'touchend .add-comment-button': 'addComment'
},
addComment: function() {
this.$(".comment-popup").popup('open', { history: false });
return false; // Stop bubbling.
}
});
I'm using history: false because this popup is actualy part of subpage.
The code looks very simple, I'm just can't understand why it can disappear, and why this happen only on android devices.
Thanks, and sorry for my bad english.
I spent hours trying to fix this problem.
Finally I ended up doing the following two things that seemed to fix the problem.
1 - Use the uncompressed jqm file. i.e jquery.mobile.1.2.0.js
2 - I was triggering the popup programatically using the 'tap' option - once changed to the 'click' option it worked.
$('.option').live('click', function() {
$('#popup-div').popup('open');
});
I spent hours trying to fix this problem.
Finally I ended up doing the following two things that seemed to fix the problem.
this code snippet may help you ->
$('#testBtn').on('tap',function(e){
console.log("button clicked");
e.preventDefault();
$('#testPOPUP').popup("open");
});
Please note i have used e.perventDefault().
I didn't feel like changing my .tap() events to the click event and I didn't have a case where I could use preventDefault()so I just added a timeout to the popup('open') line. My hoverdelay in jqm is set to 150 so I set this timeout to 600 just to be on the safe side. Works fine, doesn't feel sluggish for the user.
One way to 'fix' it is by setting data-history="false" on the popup div
See also this question
JQuery Mobile popup with history=false autocloses
I have the exact same problem when trying to use popup('open') on an android 2.3 device (both in native browser and in firefox) and it works just fine on browsers on other devices. I'm also using backbone event management to open my popup (used the tap event and no aditionnal options to popup).
What I did to 'correct' the problem is that I removed the backbone event management for this event and added a listener in the render function. In your case this would look something like this :
events: {
// 'touchend .add-comment-button': 'addComment'
},
render: function() {
$(this.el).html(this.template(this.model));
$(this.el).find('.add-comment-button').tap(function(el){
this.addComment(el);
return false;
}.bind(this));
}
I have no idea where the problem comes from (must be some incompatibility between backbone and jquery mobile) and why we only see it on android but for the moment with this workaround my app seems to work fine on any device.
Edit: oops, it turns out that in my case the problem was I was missing "return false;" in the function dealing with the event.
Now that I added it, it works correctly with the backbone event management.
Sadly that doesn't explain why you have the issue and why I was seeing it only on android.
In case it helps anyone, I had the same problem occurring with Bing Maps, with the Microsoft.Maps.Events.addHandler(pin, 'click', callback) method.
Not particularly nice, but instead I stored an ID in pushpin._id and did the following:
$("#page").on('vclick', function (event) {
if (event.target.parentElement.className === "MapPushpinBase") {
$("#stopPopup").popup('open');
}
});
One brute force option is to check whether popup was hidden and reopen it.
In a loop, because the exact time the popup becomes hidden seems to be varied.
var hidden = $('#' + id + '-popup') .hasClass ('ui-popup-hidden')
if (hidden) $('#' + id) .popup ('open')
A working example: http://jsfiddle.net/ArtemGr/hgbdv9s7/
Another option could be to bind to popupafterclose:
var reopener = function() {$('#' + id) .popup ('open')}
$('#' + id) .on ('popupafterclose', reopener)
$('#' + id) .popup ('open')
Like here: http://jsfiddle.net/ArtemGr/gmpczrdm/
But for some reason the popupafterclose binding fails to fire on iPhone 4 half of the time.

android browser timers when keyboard is open

I have run into this issue where asynchronous functions do not execute when the soft keyboard is open in the android browser.
For example:
<input type='text' id='foo'/>
....
document.getElementById("foo").addEventListener("keyup", function() {
window.setTimeout(function() { alert("1"); }, 20);
}, false);
You will never see the alert as long as you remain focused on the text input. This is true for xhr callbacks as well. If you attempt to make an ajax request, the request is sent, but the oncomplete callback is never fired until after you type another character in the textbox.
Does anyone know a workaround? You can see that Google obviously has a working example with their search suggestions, though I've not yet been able to figure out what exactly their solution is yet by looking at the minified/obfuscated source.
Any insight appreciated, Thanks
Using the newest jquery lib in the style of
$("#inputnum").keyup(function(e){
if (e.keyCode != '13') {
$("#outputarea").slideUp('slow');
};
});
causes the item selected with "#outputarea" to be slid up every time - as soon as I type any letter on the software keyboard or a hardware keyboard. Might want to give the jquery lib a shot? Cross-browser compatibility is the main reason I keep going back to it.

What DOM events are available to WebKit on Android?

I'm building a mobile web app targeting Android users. I need to know what DOM events are available to me. I have been able to make the following work, but not terribly reliably:
click
mouseover
mousedown
mouseup
change
I have not been able to get the following to work:
keypress
keydown
keyup
Does anyone know the full list of what is supported and in what contexts (e.g., is onchange only available to form inputs?)? I can't find a reference for this on The Googles.
Thanks!
Update: I asked the same question on the Android developers list. I will be doing some more testing and will post my results both here and there.
OK, this is interesting. My use case is that I have a series of links (A tags) on a screen in a WebKit view. To test what events area available, using jQuery 1.3.1, I attached every event listed on this page (even ones that don't make sense) to the links then used the up, down, and enter controls on the Android emulator and noted which events fired in which circumstances.
Here is the code I used to attach the events, with results to follow. Note, I'm using "live" event binding because for my application, the A tags are inserted dynamically.
$.each([
'blur',
'change',
'click',
'contextmenu',
'copy',
'cut',
'dblclick',
'error',
'focus',
'keydown',
'keypress',
'keyup',
'mousedown',
'mousemove',
'mouseout',
'mouseover',
'mouseup',
'mousewheel',
'paste',
'reset',
'resize',
'scroll',
'select',
'submit',
// W3C events
'DOMActivate',
'DOMAttrModified',
'DOMCharacterDataModified',
'DOMFocusIn',
'DOMFocusOut',
'DOMMouseScroll',
'DOMNodeInserted',
'DOMNodeRemoved',
'DOMSubtreeModified',
'textInput',
// Microsoft events
'activate',
'beforecopy',
'beforecut',
'beforepaste',
'deactivate',
'focusin',
'focusout',
'hashchange',
'mouseenter',
'mouseleave'
], function () {
$('a').live(this, function (evt) {
alert(evt.type);
});
});
Here's how it shook out:
On first page load with nothing highlighted (no ugly orange selection box around any item), using down button to select the first item, the following events fired (in order): mouseover, mouseenter, mousemove, DOMFocusIn
With an item selected, moving to the next item using the down button, the following events fired (in order): mouseout, mouseover, mousemove, DOMFocusOut, DOMFocusIn
With an item selected, clicking the "enter" button, the following events fired (in order): mousemove, mousedown, DOMFocusOut, mouseup, click, DOMActivate
This strikes me as a bunch of random garbage. And, who's that cheeky IE-only event (mouseenter) making a cameo, then taking the rest of the day off? Oh well, at least now I know what events to watch for.
It would be great if others want to take my test code and do a more thorough run through, perhaps using form elements, images, etc.
Since this is the second most popular Android + JavaScript post on SO (which is just a sad commentary on the state of web development targeting the Android platform), I thought it may be worthwhile including a link to pkk's touch event test results at http://www.quirksmode.org/mobile/tableTouch.html and also http://www.quirksmode.org/mobile/ in general.
As of Android 1.5, the same touch(start|move|end|cancel) events that the iPhone supports work in Android as well.
One problem I found was that touchmove ends get queued up. No workaround yet.

Categories

Resources