I'm building a feature that let's users drag different items around. However, when they drag an item that's near the edge of the screen of their phone, the browser goes back to the last page. Does anyone know if it's able to disable this in a single <div> or is it impossible?
You could try the below code to prevent this.
If the touch element is the targeted div then prevent the action otherwise allow.
HTML:
<div id="tragetDiv"> </div>
window.addEventListener("touchmove", function(event) {
let target = event.target;
if (target.id === "tragetDiv") {
event.preventDefault();
}
});
you can set the draggable item's position inside the div coordinates. If it goes beyond target div simply set the bounds value to that.
Related
I have a pretty typical menu where the top items have children that fly out when you roll over. Works great above 992px. Below 992, you're supposed to click/tap the top item to get the flyout. That works fine, you get the pointer and even the file name in the link preview. But when you click/tap, it just stays on the same page and the flyout collapses. The only thing I can find is the statement below in javascript. If you delete it, the flyouts don't work at all. If you delete && e.preventDefault(), the top links work but the flyout doesn't happen.
document.addEventListener("click",function(e){
e.target.closest(".menu-item-has-children") && window.innerWidth <= 992 && e.preventDefault()
})
https://dmvnv.com/2021/
Found the answer.
The preventDefault is passed on from the parent to the children (like the bad genes that left you cross-eyed).
You need to stop the propagation. In this case, the children are list items in a second unordered list with a class of sub-menu.
$('.sub-menu').on("click", function(e){
e.preventDefault();
}).children().click(function(e) { // catch all children click
e.stopPropagation();
});
Javascript, Stop preventDefault() to pass to child element
I have a page with a JS code that selects an input's content with jQuery's $element.select() on mouse over of the input's parent.
I want to prevent the browser scrolling the input into view when it gets selected (and also gets focus I think?) it's out of sight, because the page is an array of thumbnails with the input below each one and what this does is a chain reaction that scrolls all the way to the bottom of the page, if you don't move the mouse away.
Try this code
$('#childInput').on('focus',function(e)
{
e.preventDefault();
});
$('#parentDiv').on('mouseover',function()
{
var temp= $('body').scrollTop();
var temp1=$('body').scrollLeft();
$('#childInput').select();
$('body').scrollTop(temp);
$('body').scrollLeft(temp1);
});
As you tab between input fields in a browser, the browser will automatically scroll the nearest parent container to place the next focused field within the view.
Simple JSFiddle: http://jsfiddle.net/TrueBlueAussie/pxyXZ/1/
$('.section').eq(6).find('input').focus();
For example if you open the above fiddle it selects "Sample item 7" at the bottom of the yellow window. If you press tab the "Sample text 8" field jumps up towards the middle of the parent window.
Obviously this is a great thing for normal websites, but I have a custom scrolling container in which I position & scroll everything manually. I am tracking focus changes and will use a momentum scroller to bring it into view, but how do I disable the default scrolling behavior of web-browsers? Happy to accept CSS, Javascript or JQuery solutions.
This is just winging it based on my comment above:
$('input').on('keyup',function(e){
if(e.keyCode === 9) {
var $this = $(this);
// (do your scroll thing here
// ..., function(){
$this.parent().next().find('input').focus();
// });
}
});
Long as the callback timing is correct, this will only change focus after you have already scrolled. You'll need to do your own magic to determine what to scroll to, but this should give you the focus behavior you want.
Turns out you can't smooth scroll for focus changes as the events happen in the wrong order. You get an awful delay while it scrolls the field into view, before focus is set. A better move of the item onscreen, or superfast scroll, is all we can hope for.
As suggested by PlantTheIdea (+1'ed), you need to catch the TAB key and find the next focusable item, bring it into view, then set focus to it.
In practice there are a number of issues to resolve:
Change of focus occurs on TAB keydown (not keyup).
Only match non-hidden inputs (lots of web apps have hidden fields that will go bang if you try to focus them).
Allow for the selection to tab off the first or last item on the page (otherwise the browser loses the ability to tab to its address bar)
use e.keyCode || e.which to allow for older browsers
catch event at document level to allow for cases of other inputs, outside of the scrolling area, causing it to enter the scrolling area (first or last input).
The final code looks like this:
$(document).on('keydown', ':focus', function (event)
{
if ((event.keyCode || event.which) == 9)
{
var $inputs = $(":input:not(hidden)")
var index = $inputs.index(this);
// Index previous or next input based on the shift key
index += event.shiftKey ? -1 : 1;
// If we are in the range of valid inputs (else browser takes focus)
if (index >= 0 && index < $inputs.length)
{
var $next = $inputs.eq(index);
event.preventDefault();
// Move, not scroll, to the next/prev item....
MoveIntoView($next);
$next.focus();
return false;
}
}
});
I have an ASP.NET page with a Telerik RadEditor (rich text box). When tabbing through a page, when a user gets to the text box, focus gets set to the various toolbar icons before it goes to the textarea. I added some jQuery to one page to set the focus on the text area when tabbing out of the last cell on a form:
$('input[type=text][id*=tbCost]').keydown(function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) { //If TAB key was pressed
e.preventDefault();
var editor = $('body').find("<%=RadEditor1.ClientID%>"); //get a reference to RadEditor client object
editor.setFocus(); //set the focus on the the editor
}
});
I am looking for a way to implement this functionality in the control so that it will work regardless of the page it is on. For example, in the above code, focus is only set if the user is tabbing out of the tbCost cell. I would like to be able to set the focus to the text area when a user tabs into the toolbar items.
Is there any way to detect when an element is about to get focus? I know I can see if an element has focus, but I can't think of a way to implement this functionality.
Thanks
Solution:
If anybody has this same question in the future and wants an example, here is the code I used:
$(document).ready(function () {
$('.reToolCell').focusin(function () {
var editor = $('body').find("<%=RadEditor1.ClientID%>");
editor.setFocus();
});
});
You might consider binding to a focus on the toolbar icons and redirecting focus to the text area. Although this might have unintended side effects if users are trying to tab-focus these tools in order to use them.
//on focus eventHandler for all your icons that calls a function
#('.elementtype, class or a generic way of identifying the icons'.onfocus(myFunction(this))
//the function take a parameter of your element, moves to the next sibling element and sets the focus
myFunction = (element) {
element.next().focus();
}
I have this code http://jsfiddle.net/xNHKP/6/ (not working in the fiddle for some reason which i dont get, but it works on my site - http://bit.ly/JV5I0Z )
What i want is that the contact form (click last menu item to make it appear) can be dragged, but when someone drags or clicks on the text fields, they do not gain focus and so you can't type in them. Ironically, it works on internet explorer.
So how can i make the fields gain focus when clicked on? I don't mind making them non-draggable.
Thanks
edit: code below (tried to keep it as simple as possible, including only the relevant stuff)
dragDrop = {
initialMouseX: undefined,
initialMouseY: undefined,
startX: undefined,
startY: undefined,
draggedObject: undefined,
initElement: function (element) {
if (typeof element == 'string')
element = document.getElementById(element);
element.onmousedown = dragDrop.startDragMouse;
}}
<form id="contactForm" onSubmit="return sendMail();">
<textarea id="message" rows="8"></textarea>
</form>
<script type="text/javascript">
dragDrop.initElement(document.getElementById('contactForm'));
</script>
Okay, seems you're struggling with it, here's what would I do considering what you want :
addEventlistener to your form, make it not bubble so if you click on an inner element it doesn't trigger.
let every inner element live it's life like usual, don't try to add messy events on them.
If you really want/need the user to be able to drag the form by dragging on a label or something you should explicitely filter what are the draggable elements. Then you can go back to a bubbling event and filter out what's not draggable. If it's not draggable, don't do anything else than a return so you don't have trouble with text selection.
Here's a fiddle
Okay, so here is an answer : you just have to check that it's the form being dragged and not any other of it's inner elements so just edit your code like so :
dragDrop.startDragMouse = function(e) {
dragDrop.startDrag(this);
var evt = e || window.event;
// Now check it's the correct element we're dealing with
if(evt.target.id==="contactForm") {
dragDrop.initialMouseX = evt.clientX;
dragDrop.initialMouseY = evt.clientY;
addEventSimple(document,'mousemove',dragDrop.dragMouse);
addEventSimple(document,'mouseup',dragDrop.releaseElement);
}
return false;
}
In Firebug I can see that as soon as you click on a form elemment it assigns a 'dragged' class to the form and when the mouse button is released the class is removed. You need to be assigning the 'dragged' class when the mouse button is pressed and the mouse is moved.