Scroll using Scroll-Bar Only - javascript

I am using three.js to allow users to create and edit a 3D model that involves using the scroll-wheel/two finger function, to zoom in and out. I want a second section of the page that is off the screen by default but the user can scroll down to see it. Preferably, this will be done only using the scroll bar, while the scroll-wheel can still be used.
For performance reasons, I'd prefer not to have to use something such as vue.js. Users provide data that remains on their computer that I'm using in both sections. This prevents me from just placing the data on another screen.
Overflow:hidden is out of the question because then I can not scroll to the bottom portion.
I tried using PreventDefault with several different EventListeners but none of them worked properly.
Below is the function that determines the size of the window and should include a function or the code to prevent scrolling.There aren't particular elements that shouldn't scroll, all of them shouldn't.
function onWindowResize() {
var viewWidth;
var viewHeight;
viewHeight=window.innerHeight-315;
//For Mobile
if(!UIactive && innerWidth < 640){
viewWidth= window.innerWidth;
//For Computer & Tablet
} else {
viewWidth= window.innerWidth -317;
if(window.innerHeight < 700){
viewHeight=window.innerHeight-52.67;
//Disable Scrollwheel
window.addEventListener('wheel',function(event){
//mouseController.wheel(event);
event.preventDefault();
}, false);
}
}
camera.aspect = (viewWidth) / (viewHeight);
camera.updateProjectionMatrix();
renderer.setSize(viewWidth, viewHeight);
UI.style.height= (viewHeight+'px');
}
Edit: I tried using the answer to a similar question. This did not achieve the desired result. I changed the code to be both window... and document... and a console.log statement included works but I can still scroll.
this.canvas.addEventListener('wheel',function(event){
mouseController.wheel(event);
return false;
}, false);
I then proceeded to try using preventDefault again and recieved the following error
Unable to preventDefault inside passive event listener due to target being treated as passive

Google Chrome docs say that,
With this intervention wheel/touchpad scrolling won't be blocked on document level wheel event listeners that do not need to call preventDefault() on wheel events.
Thus, you should apply the onmousewheel event on a specific div like so:
<div id="ScrollableDiv" style="height : 900px;background-color : red">
</div>
function stop(){
return false;
}
var div = document.getElementById('ScrollableDiv');
div.onmousewheel= stop;
Please refer this working fiddle.

Related

Prevent touchstart event when scrolling/swiping on mobile devices

I have a site that needs to work on mobile devices. If I touch a link while attempting to scroll down the page, it triggers the touchstart event (in most cases loading a new window, but in the case of the header, navigating through the menu). I want to be able to scroll without touchstart events being triggered. How can I accomplish this?
I've figured out a solution that works for most clickable items on the page:
$(document).bind("touchstart", function (e) {
touchStartPos = $(window).scrollTop();
}).bind("touchend", function (e) {
var distance = touchStartPos - $(window).scrollTop();
if (distance > 20 || distance < -20) {
e.preventDefault;
}
});
A few items on my page seem to not get bound, but you can just specifically bind each item as needed in addition to doing a general $(document).bind().

Enable an event listener when the context menu closes [duplicate]

I'm catching the contextmenu event using jQuery like this:
$(document.body).on("contextmenu", function(e){
//do stuff here
});
So far, so good. Now I want to execute some code when it closes but I can't seem to find a correct solution for this.
Using something like the following would catch some of the cases, but not nearly all:
$(document.body).on("contextmenu click", function(e){});
It wouldn't be executed when:
the browser loses focus
an option in the contextmenu is chosen
the user clicks anywhere in the browser that's not on the page
note: I'm not using a jQuery context menu, I'm just using it to catch the event.
Following code may help you. jsfiddle
var isIntextMenuOpen ;
$(document).on("contextmenu", function(e){
isIntextMenuOpen = true;
});
function hideContextmenu(e){
if(isIntextMenuOpen ){
console.log("contextmenu closed ");
}
isIntextMenuOpen = false;
}
$(window).blur(hideContextmenu);
$(document).click(hideContextmenu);
I needed to detect when a context menu closes and so I came up with a solution.
Fiddle: https://jsfiddle.net/kexp0nmd/1/
var premenuelem;
var TempContextMenuCloseHandler = function(e) {
console.log('closed!');
//console.log(e);
window.removeEventListener('keyup', TempContextMenuCloseHandler, true);
window.removeEventListener('mousedown', TempContextMenuCloseHandler, true);
window.removeEventListener('focus', TempContextMenuCloseHandler, true);
var focuselem = document.getElementById('tempfocus');
if (focuselem === document.activeElement) premenuelem.focus();
focuselem.style.display = 'none';
};
var TempContextMenuHandler = function(e) {
console.log('open!');
//console.log(e);
premenuelem = document.activeElement;
var focuselem = document.getElementById('tempfocus');
focuselem.style.display = 'block';
focuselem.focus();
window.addEventListener('keyup', TempContextMenuCloseHandler, true);
window.addEventListener('mousedown', TempContextMenuCloseHandler, true);
window.addEventListener('focus', TempContextMenuCloseHandler, true);
};
window.addEventListener('contextmenu', TempContextMenuHandler, true);
html, body { min-height: 100%; }
<textarea></textarea>
<div id="tempfocus" tabIndex="-1" style="left: 0; bottom: 0; height: 50px; width: 100%; background-color: #CCCCCC; display: none; position: fixed; outline: none;"></div>
Tested and verified working as of May 2020 on Edge, Firefox 76, and Chrome 80 for both mouse and keyboard. Mobile/touch support unknown.
The key aspect of this solution is using an element that has a tabIndex on it. By showing and moving focus to that element (focus stealing) before the context menu appears causes Edge and Chrome to send a focus change event when the user later closes the context menu. I made the background of the div gray so it could be seen - in production, make it a transparent background and style it up however you want.
The keyup handler catches the release of the Escape/Enter key for when the keyboard closes the context menu. The mousedown handler catches mousedown events in Firefox only.
As far as I can tell, there is no way to know for certain what option a user selected or even if they did, in fact, select an option. At the very least, it allows for consistent detection of context menu open/close across all major browsers.
The textarea in the example is just there to give something else to play with for focus handling.
While this solution involves temporary focus stealing, it is the cleanest, cross-browser solution until browser vendors and the W3C add an 'exitcontextmenu' event or some such to the DOM.
One minor bug I just ran into: Showing the context menu and switching away to another application closes the context menu but does not fire the closed event right away. However, upon switching back to the web browser, the event fires and the close handler runs. Adding a 'blur' capture to the window might solve that but then I'd have to re-test everything and it might break something (e.g. fire blur on opening the context menu). Not worth fixing for the extremely rare occasion this might happen AND the handler still fires - it's just visibly delayed.

Mobile timed touch event

I'm trying to set up an event to display some sharing options using touchstart & touchend. This is a pretty standard function in native apps but I haven't seen it much on the mobile web. The event will allow users to tap the main content area of the site and it the tap is longer than 1 second then an options box will slide on screen displaying options for sharing the page content.
The function below works for the first event, but if users trigger the event more than onces it fires without the 1 second requirement to fire the event.
Can anyone suggest a better approach or see why the timer isn't working every time?
if ( typeof ontouchstart != 'undefined' && typeof ontouchend != 'undefined' ) {
var touchStartOrClick = 'touchstart', touchEndOrClick = 'touchend';
} else {
var touchStartOrClick = 'click', touchEndOrClick = 'click';
};
function shareTog(){
$('.sharing-pop').animate({width: 'toggle'});
}
var touchTrigger;
$('#content').bind(touchStartOrClick, function(){
setInterval(function(){
touchTrigger = true;
}, 1000);
}).bind(touchEndOrClick, function(){
window.clearInterval();
if(touchTrigger == true){
shareTog();
touchTrigger = false;
}
});
I'm aware this would be much easier to do with jQuery Mobile but unfortunately it's not an option.
zepto is a good choice for you. Its touch module offers a good event handler.
Or you can check the source code of zepto touch
I catch your drift but I dont think it's a good solution in a web browser.
On Android for example, you already get a popup when you're longpressing content on a webpage.
You will have to block that event handler, but that means you're going to get native.

how to reverse e.preventDefault() from the body?

I have this:
function dontMove(event) {
// Prevent page from elastic scrolling
event.preventDefault();
}
&
<body ontouchmove="dontMove(event);">
This, on the ipad, stops it from being draggable and does not allow that grey background the ipad has when you drag a whole page around to show up.
I have seen on another website that its possible to reverse that in another div, so that div is completely draggable again.
Does anyone know how to reverse it?
I have also tried using this to prevent it (in the document.ready):
document.ontouchmove = function(e){
e.preventDefault();
}
& this to enable it:
function doTouchMove(state) {
document.ontouchmove = function(e){
return state;
}
}
Then I put this to activate it.
<img ontouchmove="doTouchMove(state);" src="../jpeg/pages/01.jpg" class="touch"/>
This didn't seem to work
Is there anything wrong with this?
Or any other way that might work?
This is exactly why bubbles is slightly better(at least in my opinion).
bubbles is cross browser, so you should be able to replace.
e.preventDefault()
with
e.bubbles = false;
and then latter in your code, you could potentially reset bubbles to true.
If the above isn't an option then just ignore. :D
An alternative(if you are just working with an iPad) is to just reverse how the DOM works.
document.addEventListener('click', function(){}, true );
This will force the event to work in the other direction.
Document click execute
|
|
v
Element click execute
try this post, HTML with event.preventDefault and erase ontouchmove from body tag.
Mine looks like this
<script>
// Get touch move enevt from IOS
document.ontouchmove = function (event) {
if (!event.elementIsEnabled)
event.preventDefault();
};
// Get touch move enevt from IOS
function enableOnTouchMove(event) {
event.elementIsEnabled = true;
};
</script>
then enable ontouchmove on every tag you want. ie:
<div ontouchmove="enableOnTouchMove(event)" id="listing">
I managed to solve it with
$('#form1').unbind('submit').submit();
You can solve it by preventing the event only if it comes from the body:
document.ontouchmove = function(event){
if(event.target.tagName == "BODY"){
event.preventDefault();
}
}

JS: How to prevent the default action on images in browsers?

In IE, for example, when you press the left button on an image and keeping it pressed try to move the mouse, the drag n' drop action is taking place; how could I prevent this default action so that doing that way nothing will happen. I am building an image cropper, so you should understand why I need that. I am not much interested in knowing how to do so with help of jQuery or the like. As I study JavaScript, I prefer coding in plain-vanilla JS. It is important for me to learn how to make it cross-browser if there are any differences for such a thing.
Just like August's, but plain JS:
var imgs = document.getElementById("my_container")
.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].onmousedown = function () {
return false;
};
}
If you want to do it 'new-style', google for 'addEventListener()' (all browsers but...) and 'attachEvent()' (...IE) methods.
Here's one in jQuery:
$("#my_container img").mousedown(function () {
return false;
});
http://www.google.com/search?q=cross+browser+event+hooking will probably teach you everything you need to know about cross browser event hooking. I don't know how to hook events without a framework, because that's an edge case IMHO. In The Real World (tm), you'll always use a framework.
The core here is that you have to stop the mousedown event from running. This will make drag and drop impossible, if you hook the event on text you won't be able to select that text, and so on.
If you're building an image cropper, you're going to put some kind of overlay on the image, probably a relatively or absolutely positioned div, inside of which you will "draw" a rectangle when the user clicks, holds and drags. This will make it impossible for the user to drag the image itself, so no fix for that is needed.
Even if you do not use an overlay, you are still going to hook the mousedown event - there is no other way to implement a JS cropper as far as I know. Hooking that event will by itself be enough to prevent the browser from initiating a drag and drop action.
I'm using code similar to the following to prevent dragging, which has the advantage of targetting actual drag-related events rather than the generic mousedown (which could conceivably have side-effects). Works in all the mainstream browsers except Opera.
function cancellingEventHandler(evt) {
evt = evt || window.event;
if (evt.preventDefault) {
evt.preventDefault();
} else if (typeof evt.returnValue !== "undefined") {
evt.returnValue = false;
}
return false;
}
function disableDragging(node) {
node.ondragstart = cancellingEventHandler;
node.ondraggesture = cancellingEventHandler;
}
disableDragging( document.getElementById("anImage") );

Categories

Resources