I have this code here:
var t
$('#camera').on("touchstart", function(e) {
event.preventDefault();
t = setTimeout(function(){ $("#filters").addClass("reveal-filters"); }, 1000);
});
$('#camera').on("touchend", function(e) {
clearTimeout(t);
});
I've successfully disabled the context menu but how can I remove this black box that appears in chrome when you touch and hold?
Thanks
I found those articles useful:
Disable scrolling when touch moving certain element
Disable Hold Box on ie11 W8.1 Touch Device
https://msdn.microsoft.com/en-us/library/jj583807(v=vs.85).aspx
Unfortunately, the event "MSHoldVisual" seems only to be supported on Edge/IE, I couldn't find a similar thing for Chrome.
Related
I'm making a simple player motion in Javascript canvas. (Up down left right)
I created 4 buttons on screen for mobile players. I used the following code for the buttons as I wanted to move the player until the button is released.
upBtn.addEventListeter('mousedown',()=>{
let interval=setInterval(()=>{
player.y--;
}, 50);
upBtn.addEventListener('mouseup',()=>{
clearInterval(interval);
});
});
The above code works perfectly when the buttons are clicked in a computer. But in mobile it is not working.
I also tried to use touchdown and touchup but it didn't work.
What changes should I make in the code to make it work in mobile also?
Thanks in advance
You're looking for touchstart and touchend
function upFunc(event) {
//prevents some devices to emulate the click event
event.preventDefault();
let interval=setInterval(()=>{
player.y--;
}, 50);
upBtn.addEventListener('mouseup',downFunc);
upBtn.addEventListener('touchend',downFunc);
}
function downFunc(e) {
e.preventDefault();
clearInterval(interval);
}
upBtn.addEventListeter('mousedown', upFunc);
upBtn.addEventListeter('touchstart', upFunc);
Note that to support both mouse and touch in vanilla js you'll have to add both event listeners.
Also, some devices emulate the mouse events, so you can use preventDefault() to make sure your functions fires only once.
I had a similar issue and eventually solved it. I don't remember all the details of how I got to the end result but here is the code I eventually used to get it to work.
It is for controlling a camera robot. Pressing and holding the forward arrow makes the robot move forward while the button is held down and stops as soon as the button is released.
It works both on PC browser and on smartphone browsers. I've only tried it on a couple of browsers on Samsung though.
It uses the onmousup and onmousedown for the PC while for the smartphone it is a bit more complicated using the touch events.
Also important is the oncontextmenu="absorbEvent_()" which prevents the context menu from appearing when you hold down a button.
<button id="moveForward"
onmousedown="moveForward_onmousedown()"
onmouseup="anyMovementButton_onmouseup()"
onmouseout="anyMovementButton_onmouseout()"
ontouchstart="moveForward_onmousedown()"
ontouchend="anyMovementButton_onmouseup()"
ontouchmove="anyMovementButton_onmouseout()"
ontouchcancel="anyMovementButton_onmouseout()"
oncontextmenu="absorbEvent_()">
<svg width="34" height="34">
<polygon points="2,32 17,2 32,32" style="fill:lime;stroke:purple;stroke-width:3;fill-rule:evenodd;"></polygon>
</svg>
</button>
function moveLeft_onmousedown() {startMovement('left' ); }
function moveReverse_onmousedown() {startMovement('reverse'); }
function moveForward_onmousedown() {startMovement('forward'); }
function moveRight_onmousedown() {startMovement('right' ); }
function tiltUp_onmousedown() { singleMove('up' ); }
function tiltDown_onmousedown() { singleMove('down' ); }
function anyMovementButton_onmouseup() {stopMovement();}
function anyMovementButton_onmouseout() {stopMovement();}
// this function is for preventing context menu on mobile browser
function absorbEvent_(event)
{
var e = event || window.event;
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
}
I tried to disable auto focus of input search inside select2 especially on mobile to disable keyboard popup. However, as documented here:
select2 will not be triggering the native events. select2 will also
not be triggering non-native versions of the events, which is less of
an issue as we still have the option to add the native events without
breaking compatibility.
So the only way I could do is to try to get every input box inside select2 that was currently on focused and set lose focus, but has no luck.
$("select").select2().on("select2-open",":input",function(){
setTimeout(function(){
$(":focus").blur();
}, 50);
});
Is there any possibility that I could achieve that result above? Thanks.
Finally, I managed to find solution which works just fine for me as below:
/* Hide keyboard on select2 open event */
function hideSelect2Keyboard(e){
$('.select2-search input, :focus,input').prop('focus',false).blur();
}
$("select").select2().on("select2-open", hideSelect2Keyboard);
$("select").select2().on("select2-close",function(){
setTimeout(hideSelect2Keyboard, 50);
});
Tested on Tablet, and iOS device. In function hideSelect2Keyboard(), I searched for every current focus element, include input field which could be used to initialized select2, setting .prop('focus',false) which will remove focus and consequently disable keyboard popup on select2-open and select2-close event, by chaining .blur() is to remove focus border from element. Then I attached this function to select event open and close and it works just fine.
I hope this will help other who searching for this as me too. Thanks.
I think I've found a solution for select v3 - tested in v3.5.4.
We can use the option shouldFocusInput, which must be a function that should return true or false.
So initialize the plugin with the following code:
$(document).ready(function() {
$('select').select2({
shouldFocusInput: function() {
return false;
}
});
});
Codepen demo: https://codepen.io/andreivictor/pen/JmNzvb
If you want to disable the auto-focus only on mobile devices, my approach is to use Modernizr library, which can test for the existence of Touch Events in the browser.
So the complete code should be:
$(document).ready(function() {
$('select').select2({
shouldFocusInput: function() {
if (Modernizr.touch) {
return false;
}
return true;
}
});
});
I am not sure why, but the above solutions didn't work for me. But this one worked-
$('select').on('select2:open', function (event) {
$('.select2-search input').prop('focus',false);
});
I'm writing an app in phonegap with a specific 'zoom-in' effect when clicking on an input element (everything but the input hides and custom typeahead suggestions are shown). The view is written using backbone.js and i'm entering the 'zoomed-in' mode on focus:
events: {
'focus .search': 'startSearch',
}
In my startSearch method i'm doing all the logic to immitate the zoom-in effect.
_moveCursorToEnd: function(element) {
var val_len = element.value.length;
element.scrollLeft = val_len * 9;
setTimeout(function() {
element.selectionStart = val_len;
}, 1);
},
startSearch: function() {
window.navbar.hide();
this.$input.addClass('search-input-small');
this.$cancel.show();
var el = this.$input[0];
this._moveCursorToEnd(el);
},
The search-input-small makes the input smaller.
The setTimeout in _moveCursorToEnd is required because the effect doesn't work otherwise. The issue is that despite setTimeout having 1msec, it looks like a second cause inconvenient cursor move.
Is there any way to move the cursor to the end that would work on Safari Mobile 6 (iOS 6+) without the ugly delay?
I've ended up changing the event from focus to click and using similar code as mentioned above so that it works. Seems like the selection from a click that focused the text edit is applied after focus handler and before click handler.
Since on mobile device browser such as safari , when user drag the screen, the whole website will move along with the finger. So the common solution is :
addEventListener('touchmove', function(e) { e.preventDefault(); }, true);
This will prevent any touchmove event . However, since the browser on mobile device has no scroll bar , when user want to scroll the dialog box of jquery ui , the touchmove event need to be permit. This statement will block that event.
addEventListener('touchmove', function(e) {
if (e.target.id != 'dialog' )
e.preventDefault();
return false;
}, true);
Then I add this statement to allow the dialog box to scroll. However, this solution has flaw because the background will be draggable and move along with user finger again. How to fix this problem? Thanks.
Been dealing with this all day and found this solution. When you want it to scroll the dialog on safari mobile on ipad/iphone/ipod, you need to use this:
if (/iPhone|iPod|iPad/.test(navigator.userAgent)) {
$('iframe').wrap(function () {
var $this = $(this);
return $('<div />').css({
width: $this.attr('width'),
height: $this.attr('height'),
overflow: 'auto',
'-webkit-overflow-scrolling': 'touch'
});
});
}
Anyone have any idea how to detect a mouseup event on a scrollbar? It works in FF, but not in Chrome or IE9.
I set up a quick demo: http://jsfiddle.net/2EE3P/
The overall idea is that I want to detect a scrollEnd event. There is obviously no such thing so I was going with a combination of mouseUp and timers, but mouseUp isn't firing in most browsers! The div contains a grid of items so when the user stops scrolling I want to adjust the scroll position to the nearest point that makes sense, e.g. the edge of the nearest cell. I don't, however, want to automatically adjust the position if they're in the middle of scrolling.
I'll also happily accept any answer that gives me the equivalent of scrollEnd
found a solution that works without timers but only if you are scrolling the complete window.
switch(event.type){
case 'mousedown':
_btnDown = true;
//THIS IS ONLY CAUSE MOUSEUP ON SCROLLBAR IS BUGGY
$(document).bind('mousemove',function(event){
if(event.pageX < ($(window).width() - 30)){
//mouse is off scrollbar
$(this).unbind(event);
$(this).trigger('mouseup');
}
});
break:
case 'mouseup':
//do whatever
_btnDown = false;
break;
}
pretty dirty .. but works.
Using jquery there is a .scroll event you can use. Maybe use a global variable to keep track of when .scrollTop() (it returns the number of pixels there are above the screen) has stopped changing? Still creates a race condition, but it should work.
Answering my own question so I can close it -- there is no good solution to this, so timers it is...
I was handling the same problem. For me IE9 don't emit mouseup event for scrollbars. So, I checked and on IE9 when you "mouseup" it emits a mousemove event. So what I did was monitor scrolling, and monitor mousemove. When user is scrolling, and a mousemove event happens, then I understand it as a mouseup event. Only do this check for IE9, cheching the proto property availability. The code will also run for Opera, but Opera has the mouseup and then no problem for me when both events happens. Here is the code, I write AngularJS + ZEPTO code, so get the idea and write your own code, don't expect to copy&paste this code directly:
// Global for scrolling timeout
var q;
// Action to do when stop scrolling
var updatePosition = function() {
// Put the code for stop scrolling action here
}
$(document).on('mousemove', function(e) {
console.log('MOUSE MOVE ' + e.pageX + ',' + e.pageY);
if(!('__proto__' in {})) {
// for IE only, because it dont have mouseup
if($scope.scrolling && $scope.mouse_down) {
console.log('FAKE MOUSE UP FOR IE');
// Only simulate the mouseup if mouse is down and scrolling
$scope.scrolling = false;
$scope.mouse_down = false;
// Update Position is the action i do when mouseup, stop scrolling
updatePostition();
}
}
});
$(window).on('scroll', function(){
console.log('SCROLLING');
// Set the scrolling flag to true
if(!$scope.scrolling) {
$scope.scrolling = true;
}
// Stop if for some reason you disabled the scrolling monitor
if(!$scope.monitor_scrolling) return;
// Monitor scroll with a timeout
// Update Position is the action i do when stop scrolling
var speed = 200;
$timeout.cancel(q);
q = $timeout(updatePostition, speed);
});
$(window).on('mousedown', function() {
console.log('MOUSE DOWN');
// Stop monitor scrolling
$scope.monitor_scroll = false;
// Set that user is mouse down
$scope.mouse_down = true;
});
$(window).on('mouseup', function() {
console.log('MOUSE UP');
// Enable scrolling monitor
$scope.monitor_scroll = true;
// Change mouse state
$scope.mouse_down = false;
// Action when stop scrolling
updatePostition();
});
Was fighting with this problem. My system also runs for mobile and I have a large horizontal scrolling, that always when user stop scrolling, it need to find the actual item the used is viewing and centralize this item on screen (updatePosition). Hope this can help you. This is to support IE9+, FF, Chorme and Opera, I'm not worrying with old browsers.
Best Regards
Is very late but.... there are solution with any scroll in any part of your page.... I do it with the next code...
onScroll = function(){
$(window).unbind("mouseup").one('mouseup',function(e) {
alert("scroll up")
});
};
$(window).bind("scroll", onScroll);
body{
height:5000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>