mobile Safari: prevent scroll page when focus on input - javascript

I'm trying to prevent scroll page when user tap on input:
<pre class="js-parent">
<input value="tap to focuss" readonly>
</pre>
$("input").on("focus", function(e) {
e.preventDefault();
e.stopPropagation();
});
$("input").on("click", function(e) {
e.preventDefault();
e.stopPropagation();
this.setSelectionRange(0, 9999);
});
Few problems:
1) when user click on input page scroll to element (to the top of the page)
2) when focus is active, parent block lose position: fixed
demo
demo with code

You can trick safari into thinking that the current focused input is at the top of the page, so that no need to scroll down, by following trick:
$(document).on('touchstart', 'textarea, input[type=text], input[type=date], input[type=password], input[type=email], input[type=number]', function(e){
var intv = 100;
var $obj = $(this);
if (getMobileOperatingSystem() == 'ios') {
e.stopPropagation();
$obj.css({'transform': 'TranslateY(-10000px)'}).focus();
setTimeout(function(){$obj.css({'transform': 'none'});}, intv);
}
return true;
});
You can find more details in following thread, which shows how to do this for android os, too.
jquery mobile How to stop auto scroll to focused input in Mobile web browser

Here is a Vanilla JS version based on the first answer. It prevents IOS & mobile Safari from scrolling the screen when the soft keyboard is opened via the focus event created when clicking into an input.
It works perfectly in iOS 15.2.1
It also works very well with the 'focus' event.
element.addEventListener('touchstart', (event) => {
event.stopPropagation();
element.style.transform = 'TranslateY(-10000px)'
element.focus();
setTimeout(function () { element.style.transform = 'none' }, 100);
});

Related

How can I make a nested element not draggable in a draggable container?

I'm using HTML5 drag and drop on a parent container, but I want to disable the drag effect on some of its children, specifically an input so that users can select/edit input content easily.
Example:
https://jsfiddle.net/Luzub54b/
<div class="parent" draggable="true">
<input class="child" type="text" value="22.99"/>
</div>
Safari seems to do this for inputs by default so try it on Chrome or Firefox.
I was looking for something similar and found a possible solution using the mousedown and mouseup events. It's not the most elegant solution but it's the only one that worked consistently for me on both chrome and firefox.
I added some javascript to your fiddle:
Fiddle
;
(function($) {
// DOM Ready
$(function() {
$('input').on('mousedown', function(e) {
e.stopPropagation();
$('div.parent').attr('draggable', false);
});
$(window).on('mouseup', function(e) {
$('div.parent').attr('draggable', true);
});
/**
* Added the dragstart event handler cause
* firefox wouldn't show the effects otherwise
**/
$('div.parent').on({
'dragstart': function(e) {
e.stopPropagation();
var dt = e.originalEvent.dataTransfer;
if (dt) {
dt.effectAllowed = 'move';
dt.setData('text/html', '');
}
}
});
});
}(jQuery));

Iphone 5 jquery modal dialog

I have a prob that i think is common on iPhone devices. I have a jquery modal dialog popup and when i scroll on this modal and touch on a select element after touching the done button is scrolls me to the top. By default my modal position is fixed. I found an article that says if you change it to position absolute it will be fixed but actually it does not. Please find below my code and give some help guys. Thanks
j('.modal input[type=text], .modal select').each(function () {
if ('ontouchstart' in document.documentElement) {
var osVar = new UAParser().getOS();
var verticalPos = "";
if (osVar == "iOS") {
j(this).on('focus', function (e) {
verticalPos = j(this).offset().top;
j('.modal').css("position", "absolute");
});
j(this).on('blur', function (e) {
j('.modal').css("position", "fixed");
j(this).scrollTop(verticalPos);
});
}
}
});

jQuery manual click option if scroll event fails

I am using the following code to show more content when the user scrolls to the bottom of the screen.
$(document).ready(function() {
$('#items').eq(0);
$("#items .itemDiv").slice(12).hide();
var rowCount = $('#items .itemDiv').length;
$(window).scroll(function showMore (e) {
e.preventDefault();
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
$("#items .itemDiv:hidden").slice(0, 12).fadeIn("slow");
if ($("#items .itemDiv:hidden").length == 0) {
if (!('appendEnd' in showMore)) {
showMore.appendEnd = true;
$(".itemscrl").append("<div>You have reached the end.</div>");
}
}
}
});
The problem is that it does not work on some devices (e.g. Android Chrome), so I would like to include the option of allowing the user to click an <a> element to trigger the function.
Any ideas on how to implement this?
I am suspecting that when you call e.preventDefault(); in your code you are breaking the scrollability of a page.
Remove the following from your code, I don't see any reason for disabling the default scrollability of a page:
e.preventDefault();

mouseup event is not triggered after scroll bar moves in IE and Safari

I did a search in the site but didn't get useful info for my case. A simple demo can be found at jsfiddle. When I moved onto the div scroll bar and pressed the mouse, the event 'mousedown' was fired. And then I scrolled the bar, released the mouse. Unfortunately the event 'mouseup' was not fired in IE/Safari. Chrome and Firefox work fine. Is there a work-around solution for IE and Safari? Thanks!
Sample Code :
<div class="box">
<div class="box-inner">
</div>
</div>
<p id="text"></p>
jQuery :
$(document).ready(function() {
var $txt = $('#text');
$('.box').mouseup(function() {
$txt.text('mouseup');
});
$('.box').mousedown(function() {
$txt.text('mousedown');
});
});
Did more search in the site and got similar question. A solution proposed in the question is not prefect but worthy of trying.
$(document).ready(function() {
var $txt = $('#text'), $win = $(window), $doc = $(document);
$win.on('mousedown', function(event) {
$txt.text('mousedown');
if(event.pageX < ($win.width() - 10)) {
return;
}
$doc.on('mousemove', function(event) {
if(event.pageX < ($win.width() - 10)){
//mouse is off scrollbar
$(this).unbind(event);
$win.trigger('mouseup', ['manual fire']);
}
});
}).on('mouseup', function(event, str) {
$txt.text('mouseup: ' + str);
});
});
the mouseup fired for me in Safari... I can't test in IE as I'm on a Mac, but please try this:
http://jsfiddle.net/CmW9e/4/
$(document).ready(function() {
var $txt = $('#text');
$('.box').on("mousedown.box", function() {
$txt.text('mousedown');
$(document).one("mouseup.box", function() {
$txt.text('mouseup');
});
});
});
Basically binding the mouseup to the Document when you mousedownand then removing the bind after it's triggered :) this way the mouseup will always trigger no matter where the mouse is

Jquery Blur event on div scrolbar

I have a div with scroll bar.
Using Firefox when I click on scroll bar to drag it down to see the div list the blur event is fired and hides my div which I have set to hide when blur is fired.
How can I prevent the blur to fire when the scroll bar is used:
$("#mydiv").blur(function () {
$('#mydiv').fadeOut();
console.log("fadeout blur");
});
I display this div using:
$('#mydiv').fadeIn();
I want the div to hide when its not active but not hide when I try to click on the scroll bar.
May be this is what you are looking for
$(document).ready(function(){
$('#mydiv').fadeIn();
$("body").bind('click', function(ev) {
var myID = ev.target.id;
if (myID !== 'mydiv') {
$('#mydiv').fadeOut();
}
});
});
This will bind the click event with the body and also check the id of the element which triggers the click event. If it doesn't match the DIV, the div will be closed else the div will be always open.
You can do this one:
$(window).scroll(function() {
$('#mydiv').css('display','block');
});
var scrolling = false, scrollingTimeout, blurTimeout;
$(window).scroll(function () {
if (scrollingTimeout) {
clearTimeout(scrollingTimeout);
}
scrolling = true;
scrollingTimeout = setTimeout(function(){
scrollingTimeout = null;
scrolling = false;
}, 300);
});
$("#mydiv").blur(function () {
var that = $(this);
if (!scrolling) {
that.fadeOut();
} else {
if (blurTimeout) {
clearTimeout(blurTimeout);
}
blurTimeout = setTimeout(function () {
blurTimeout = null;
that.focus();
}, 600);
}
});
see jQuery scroll() detect when user stops scrolling and Can I declare logic on jQuery for the start and end of a scrolling event?
Seems your scroll bar is not formed within the div & clicking on it causes call to blur. Please check the css/style used for showing scroll for div is doing what you are expecting (forming scroll bar inside div), if this is the case then use a parent div over both(div & scroll bar) & use focusOut/blur event on parent div containing both.

Categories