How to disable scroll function? - javascript

I have problem with "double scrolling"; This is screen from my app:
As you can see, the space for adding tables is surrounded by a scroll bar.
I just need the scroll function to zoom in and out of my diagram, not to move it up and down. The current situation is that if I run my function that zooms in and out on the diagram, it also scrolls up or down. It makes such a double scroll which makes no sense.
Is it possible to turn off only the "scroll" function without turning off the scroll bars on the sides?
This is some code (my event wheel)(i am using library "MindFusion Diagramming"):
document.addEventListener('wheel', function (e) {
var zoom = diagram.getZoomFactor();
zoom -= e.deltaY / 35;
if(zoom > 70 && zoom < 200 )
{
diagram.setZoomFactor(zoom);
}
//e.preventDefault();
});
And this is an error when I uncomment e.preventDefault ()
My divs (content is an area with scrollbars):
<div id="content" style="position: static; width: 1600px; height: 700px;" >
<!-- The Overview component is bound to the canvas element below -->
<div style="position: absolute; right: 120px; width: 200px;
height: 200px; border: 1px solid #ffffff; background-color: #c0c0c0;">
<canvas id="overview" width="200" height="200">
</canvas>
</div>
<!-- The Diagram component is bound to the canvas element below -->
<div style="position: static; width: 100%; height: 100%; overflow: auto;">
<canvas id="diagram" width="2100" height="2100">
This page requires a browser that supports HTML 5 Canvas element.
</canvas>
</div>
</div>

Try,
document.addEventListener('wheel', function (e) {
e.preventDefault();
var zoom = diagram.getZoomFactor();
zoom -= e.deltaY / 35;
if(zoom > 70 && zoom < 200 )
{
diagram.setZoomFactor(zoom);
}
}, { passive : false});
reference: what are passive event listeners

I assume you overrode the scroll event to achieve your zoom functionality. You would need to call the preventDefault function on the event object you get in your event listener.
Edit:
Your event listener is passive because scroll event listeners are usually disruptive to user experience. To register it as non-passive:
document.addEventListener('wheel', function (e) {
var zoom = diagram.getZoomFactor();
zoom -= e.deltaY / 35;
if(zoom > 70 && zoom < 200 )
{
diagram.setZoomFactor(zoom);
}
e.preventDefault();
}, {passive: false});

Related

Zoom page with mouse wheel, click and drag to pan

How would I go about making a scroll-and-pan effect with the mouse wheel for the entire page? Basically like any 2D editor with the scroll to zoom, click and drag to pan but for the entire body.
I haven't been able to find anything online about it.
If you don't know where to start, you will very soon hit another wall, because knowing where to start is the easy part. Here is a rough guide:
Add event listener to the wheel event (learn how](https://stackoverflow.com/a/51276012/104380))
Start with an initial (current) zoom value and calculate the delta from the wheel event and update your zoom value.
Use the zoom value to manipulate the scale of the page in some form. You can use CSS transform: scale() for that, on the body element.
Add event listener for the mousemove event (learn how](https://developer.mozilla.org/en-US/docs/Web/API/Element/mousemove_event))
Act upon the detected mouse move, and calculate how much you need to pan the zoomed body element in order to reach any of the 4 edges, and not beyond.
panning may be done via CSS transform: translate(x,y)
Implementation I made based off of vsyncs answer:
window.onload = init;
let root;
let content;
let zoom = 1.0;
let translateY = 0;
let translateX = 0;
let middleMouseDown = false;
function init(){
content = document.getElementById("content");
root = document.getElementById("root");
root.addEventListener("wheel", (event)=>{
zoom += event.wheelDelta / 1000;
if(zoom > 2.0){zoom = 2.0}
else if (zoom < 0.5) {zoom = 0.5}
console.log(zoom);
transform();
})
root.addEventListener("mousedown", (event)=>{
event.preventDefault();
middleMouseDown = (event.button == 1);
})
root.addEventListener("mouseup", (event)=>{
if(event.button == 1){
middleMouseDown = false;
}
})
root.addEventListener("mousemove", (event)=>{
// console.log(event);
if(middleMouseDown){
translateY += event.movementY;
translateX += event.movementX;
transform();
}
})
}
function transform(){
content.style.transform = `scale(${zoom}, ${zoom}) translate(${translateX}px, ${translateY}px)`;
}
body{
margin: 0px;
}
#root{
width: 400px;
height: 400px;
border: 1px solid red;
overflow: scroll;
}
#content{
width: 200px;
height: 200px;
border: 1px solid black;
}
<html lang="en">
<head>
<link rel="stylesheet" href="index.css">
<script src="main.js"></script>
</head>
<body>
<div id="root">
<div id="content">
</div>
</div>
</body>
</html>

Attach mouse movement to a div with Iframe inside

In my JS code, I've added a EventListener on mousemove & touchmove, which makes it so that my div follows the cursor. (as such)
CSS:
<style>
body {
padding: 0;
margin: 0;
height: 100vh;
background: linear-gradient(135deg, #8fc7f1, #7173f5);
overflow: hidden;
}
#my-div {
width: 300px;
height: 250px;
background-color: #ffffff;
position: absolute;
}
</style>
HTML:
<div id="my-div">
<h1>Hello</h1>
</div>
JAVASCRIPT:
let myDiv = document.getElementById("my-div");
//Detect touch device
function isTouchDevice() {
try {
//We try to create TouchEvent. It would fail for desktops and throw error
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
const move = (e) => {
//Try, catch to avoid any errors for touch screens (Error thrown when user doesn't move his finger)
try {
//PageX and PageY return the position of client's cursor from top left of screen
var x = !isTouchDevice() ? e.pageX : e.touches[0].pageX;
var y = !isTouchDevice() ? e.pageY : e.touches[0].pageY;
} catch (e) {}
//set left and top of div based on mouse position
myDiv.style.left = x - 150 + "px";
myDiv.style.top = y - 120 + "px";
// myDiv.style.opacity = 0;
// console.log(myDiv.getBoundingClientRect())
};
//For mouse
document.addEventListener("mousemove", (e) => {
move(e);
console.log("Mouse")
});
//For touch
document.addEventListener("touchmove", (e) => {
move(e);
});
JSFIDDLE CODE
What I'm trying to do is to add a iframe inside my div and the div should still follow the cursor, but when I add the iframe inside the div, then the EventListener stops working and my div stops following the cursor. I'm not sure what the issue is. (as such)
<div id="my-div">
<iframe src="https://example.com/" width="300" height="250">
</div>
JSFIDDLE CODE WITH IFRAME
Any help and suggestion is appreciated!
You forgot the closing iframe tag
<div id="my-div">
<iframe src="https://example.com/" width="300" height="250"></iframe>
</div>
I think you should change the position of your div to relative and the position of your iframe to absolute.

Change image shown in fixed div when another div is in viewport

I have a fixed div containing an image that scrolls with the user from the top of the page. As new content divs enter the viewport I want the image to change.
I found a related piece of code that will change the image based on how far a user scrolls in pixels. This works, but only if the viewport is a specific size, else the image changes too early/late:
Example
I'm trying to modify this so that the change is instead based on when another div comes into view so that it works no matter the screen size (content div heights are set with relative units). I think this can be done if the other divs positions are saved to a variable and then used in place of the pixel values in the above code. However I can't seem to get this right, probably because I've not calculated the other div positions correctly.
$("#display1").fadeIn(1000);
$(window).scroll(function() {
var pos = $(window).scrollTop();
var first = $("#first").offset();
var second = $("#second").offset();
if (pos < first) {
hideAll("display1");
$("#display1").fadeIn(1000);
}
if (pos > first && pos < second) {
hideAll("display2");
$("#display2").fadeIn(1000);
}
etc...
});
function hideAll(exceptMe) {
$(".displayImg").each(function(i) {
if ($(this).attr("id") == exceptMe) return;
$(this).fadeOut();
});
}
You should try
getBoundingClientRect()
JS method, since It gets the position of the elements relative to the viewport. Check this answer: https://stackoverflow.com/a/7557433/4312515
Here is a quick proof of concept of changing a background image based on an element getting into view.
There are three divs. When the third div reaches the bottom of the viewport it will change the color of the background. When the third divs scroll out of the view again the background color is reset to its initial color.
Normally you should debounce the scroll event to prevent slowing down the UI. For this example I didn't debounce the event so you get a better sense of when the background is changed.
const
card3 = document.getElementById('card3'),
background = document.getElementById('background');
let
isCardVisible = false;
function checkDivPosition() {
const
cardTopPosition = card3.getBoundingClientRect().top,
viewportHeight = document.documentElement.clientHeight,
isInView = cardTopPosition - viewportHeight < 0;
if (isInView && !isCardVisible) {
background.style.backgroundColor = 'rebeccapurple';
isCardVisible = true;
} else if (!isInView && isCardVisible) {
background.style.backgroundColor = 'orange';
isCardVisible = false;
}
}
function onWindowScroll(event) {
checkDivPosition();
}
window.addEventListener('scroll', onWindowScroll);
body {
margin: 0;
}
.background {
height: 100vh;
opacity: .2;
position: fixed;
transition: background-color .3s ease-out;
width: 100vw;
}
.card {
border: 1px solid;
height: 100vh;
width: 100vw;
}
.card + .card {
margin-top: 5vh;
}
<div id="background" class="background" style="background-color:orange"></div>
<div class="card">
Card 1
</div>
<div class="card">
Card 2
</div>
<div id="card3" class="card">
Card 3.
</div>

Scrolling News Ticker Jquery - Issues

Original Source & Example:
http://www.htmldrive.net/items/show/397/Vertical-Scrolling-News-Ticker-With-jQuery-jCarouse
Hello Again!! Scrolling News Ticker Jquery with some issues:
First Issue : Internet Explorer Error Message
" Object doesn't support this property or method " Line: 269: Line 269)
ticker.mouseenter(function() { // <---Line: 269
//stop current animation
ticker.children().stop();
});
Second Issue : The only way of clicking on a news option (to be directed to the link of a page) is through the text title that in the website example is in blue color.
I would like for the user to be able to click on the whole section of the option that
includes the image aswell.
Third Issue : When the news scrolls it looks all in one, is there a way to add a line to separate each section.
Forth Issue: Is there a way to pause the automatic scrolling when a user puts the mouse
over a section?
Is there a way to add more text under the title and category?
Here is the script itself with the IE issue highlighted with an arrow on the right hand side
below:
<script type="text/javascript">
$(function() {
//cache the ticker
var ticker = $("#ticker");
//wrap dt:dd pairs in divs
ticker.children().filter("dt").each(function() {
var dt = $(this),
container = $("<div>");
dt.next().appendTo(container);
dt.prependTo(container);
container.appendTo(ticker);
});
//hide the scrollbar
ticker.css("overflow", "hidden");
//animator function
function animator(currentItem) {
//work out new anim duration
var distance = currentItem.height();
duration = (distance + parseInt(currentItem.css("marginTop"))) / 0.020;
//animate the first child of the ticker
currentItem.animate({ marginTop: -distance }, duration, "linear", function() {
//move current item to the bottom
currentItem.appendTo(currentItem.parent()).css("marginTop", 0);
//recurse
animator(currentItem.parent().children(":first"));
});
};
//start the ticker
animator(ticker.children(":first"));
//set mouseenter
ticker.mouseenter(function() {
ticker.mouseenter(function() { // <---Line: 269
//stop current animation
ticker.children().stop();
});
//set mouseleave
ticker.mouseleave(function() {
//resume animation
animator(ticker.children(":first"));
});
});
</script>
I would deeply appreciate it!!
to add line to separate each items add border-bottom:1px solid black; to the css.
after read your question i would like to show you the javascript method that i used in my site and stops when mouse over.
<div id="marqueecontainer" onMouseover="copyspeed=pausespeed" onMouseout="copyspeed=marqueespeed">
<div id="vmarquee" style="position: absolute; width: 98%;">
<!--YOUR SCROLL CONTENT HERE-->
<!--YOUR SCROLL CONTENT HERE-->
</div>
</div><style type="text/css">
#marqueecontainer{
position: relative;
width: 200px; /*marquee width */
height: 200px; /*marquee height */
background-color: white;
overflow: hidden;
border: 3px solid orange;
padding: 2px;
padding-left: 4px;
}
</style>
<script type="text/javascript">
var delayb4scroll=2000 //Specify initial delay before marquee starts to scroll on page (2000=2 seconds)
var marqueespeed=2 //Specify marquee scroll speed (larger is faster 1-10)
var pauseit=1 //Pause marquee onMousever (0=no. 1=yes)?
var copyspeed=marqueespeed
var pausespeed=(pauseit==0)? copyspeed: 0
var actualheight=''
function scrollmarquee(){
if (parseInt(cross_marquee.style.top)>(actualheight*(-1)+8))
cross_marquee.style.top=parseInt(cross_marquee.style.top)-copyspeed+"px"
else
cross_marquee.style.top=parseInt(marqueeheight)+8+"px"
}
function initializemarquee(){
cross_marquee=document.getElementById("vmarquee")
cross_marquee.style.top=0
marqueeheight=document.getElementById("marqueecontainer").offsetHeight
actualheight=cross_marquee.offsetHeight //height of marquee content (much of which is hidden from view)
if (window.opera || navigator.userAgent.indexOf("Netscape/7")!=-1){ //if Opera or Netscape 7x, add scrollbars to scroll and exit
cross_marquee.style.height=marqueeheight+"px"
cross_marquee.style.overflow="scroll"
return
}
setTimeout('lefttime=setInterval("scrollmarquee()",30)', delayb4scroll)
}
if (window.addEventListener)
window.addEventListener("load", initializemarquee, false)
else if (window.attachEvent)
window.attachEvent("onload", initializemarquee)
else if (document.getElementById)
window.onload=initializemarquee
</script>
you can view the demo at here

Once user reaches a particular point on a page, automatically scroll to particular point/achor

So, here it is:
I'll have 4 divs. Example below. Each div a particular height (around 1500px) but have a width of 100%. Each div is a different colour.
I want it so that when the user scrolls the page and reach a particular point, javascript will kick in and automatically scroll the user to the next div.
So, say the user is vertically scrolling and div #2 is appear and div #1 is disappearing. When div #1 has about 200px left, the page will automatically scroll down so that div #2 is flush with the top of the browser window.
A good example: http://thejuly16.com/ Which basically does it but can't work out how.
1
Content here
2
Content here
3
Content here
4
Content here
That page isn't doing anything for me :/
Anyway, if I get what you mean, you should have some anchors on top of every div, hook some code to the scroll event, check scrollTop() value on it, and scroll to the anchors when this value is in a desired range. You can check this fiddle and the relevant jQuery code:
$(window).bind('scroll', function(){
if (($(window).scrollTop() > 1300) && ($(window).scrollTop() < 1350)) {
window.scrollTo(0,1500);
}
});
This might be a strange behavior for the user, since scrolling up is pretty messed up. However, we can fix this by checking if the user is going up or down in the page, like in this fiddle, just checking if the last scroll position was higher or lower than the current scroll position:
var currentScroll = 0;
var previousScroll = 0;
$(window).bind('scroll', function(){
currentScroll = $(window).scrollTop();
if (($(window).scrollTop() > 1300) && ($(window).scrollTop() < 1350) && currentScroll > previousScroll) {
window.scrollTo(0,1500);
}
previousScroll = $(window).scrollTop();
});
Obviously, you'd need to add as many if statements as "jumps" you want in your page.
I have a solution as given in the code below. Somehow its not working on jsFiddle but working on my machine. Please try it in your own editor
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
var isWorking = false;
var lastScrollPosition
function adjust(oDiv) {
if(oDiv.scrollTop > lastScrollPosition && !isWorking && oDiv.scrollTop % 400 > 300) {
isWorking = true
scroll(oDiv);
} else
lastScrollPosition = oDiv.scrollTop;
}
function scroll(div) {
if(div.scrollTop % 400 > 10) {
div.scrollTop = div.scrollTop + 10;
lastScrollPosition = div.scrollTop;
setTimeout(function(){scroll(div);}, 10);
} else
isWorking = false;
}
</SCRIPT>
</HEAD>
<BODY>
<div style="height: 440px; border: solid 1px red; overflow-Y: auto" onscroll="adjust(this)">
<div style="height: 400px; border: solid 1px green"></div>
<div style="height: 400px; border: solid 1px green"></div>
<div style="height: 400px; border: solid 1px green"></div>
<div style="height: 400px; border: solid 1px green"></div>
<div style="height: 100px"></div>
</div>
</BODY>
</HTML>
I think this functionality is available with jQuery. I have tried this but I was doing this on OnClick event in Javascript. In your case, onFocus or any other suitable event like mouseover etc should work.
Hope this helps.

Categories