Horizontal scroll with mouse wheel on horizontal list
You just forget to add JQuery to your html
http://jsfiddle.net/902tjbzz/
jquery.js
: http://code.jquery.com/jquery-2.1.4.min.js
How to horizontally scroll a table with mouse wheel in react?
Use onWheel event
The
onwheel
event occurs when the mouse wheel is rolled up or down over an element.
With Element.scrollTo(), Element.scrollLeft
The
scrollTo()
method of the Element interface scrolls to a particular set of coordinates inside a given element.
element.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});
Code sample:
const onWheel = e => {
e.preventDefault();
const container = document.getElementById("container");
const containerScrollPosition = document.getElementById("container").scrollLeft;
container.scrollTo({
top: 0,
left: containerScrollPosition + e.deltaY,
behaviour: "smooth"
});
};
<div className="container" id="container" onWheel={onWheel}>
Refer: Horizontal Scrolling on React Component Using Vertical Mouse Wheel
How to do React-horizontal scroll using mouse wheel
You can use a custom scroll function as a ref to your div.
export function useHorizontalScroll() {
const elRef = useRef();
useEffect(() => {
const el = elRef.current;
if (el) {
const onWheel = e => {
if (e.deltaY == 0) return;
e.preventDefault();
el.scrollTo({
left: el.scrollLeft + e.deltaY,
behavior: "smooth"
});
};
el.addEventListener("wheel", onWheel);
return () => el.removeEventListener("wheel", onWheel);
}
}, []);
return elRef;
}
The above function can be imported and used as follows:
<div className="App" ref={scrollRef} style={{ overflow: "auto" }}>
<div style={{ whiteSpace: "nowrap" }}>
<Picture />
</div>
</div>
I created a codesandbox as an example.
react horizontal scroll to section with mouse wheel
I've modified your sandbox Working Demo.
Did following changes:
- Created
navRefs
for each menu item. And did the same thing withnavRefs
as you did withscrollRefs
.
// called it when user scrolls vertically, or clicks on a menu item
navRefs.current[i].current.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "center"
});
- Changed logic to find currently focused content.
const isVisible =
elemTop < window.innerHeight / 2 && elemBottom > window.innerHeight / 2;
In short if content is on viewport's horizontal center then select it. This avoids selecting multiple contents if many of them are in viewport at the same time.
- Used a flag to avoid executing
scrollHandler
when user clicks on a menu item. Also avoided the horizontal scroll events on navbar. - In CSS hide horizontal scrollbar on navbar. And added red underline to selected menu item.
import "./styles.css";
import React, { createRef, useRef, useState, useEffect } from "react";
var scrolling = false;
export default function App() {
const scrollRefs = useRef([]);
const navRefs = useRef([]);
const [active, setActive] = useState(0);
const list = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8",
"Item 9",
"Item 10"
];
scrollRefs.current = [...Array(list.length).keys()].map(
(_, i) => scrollRefs.current[i] ?? createRef()
);
navRefs.current = [...Array(list.length).keys()].map(
(_, i) => navRefs.current[i] ?? createRef()
);
const scrollTo = (index) => {
console.log("setting scrolling" + scrolling);
scrolling = true;
scrollRefs.current[index].current.scrollIntoView({ behavior: "smooth" });
setActive(index);
setTimeout(() => {
scrolling = false;
navRefs.current[index].current.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "center"
});
}, 1000);
};
const scrollHandler = (e) => {
// handle scroll only on body
// we don't want to handle horizontal scroll on nav bar
if (e.target !== document) return;
if (scrolling === true) return;
const scrollRefsElements = scrollRefs.current;
scrollRefsElements.forEach((el, i) => {
const rect = el.current.getBoundingClientRect();
const elemTop = rect.top;
const elemBottom = rect.bottom;
const isVisible =
elemTop < window.innerHeight / 2 && elemBottom > window.innerHeight / 2;
if (isVisible) {
navRefs.current[i].current.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "center"
});
setActive(i);
}
});
};
useEffect(() => {
window.addEventListener("scroll", scrollHandler, true);
return () => {
window.removeEventListener("scroll", scrollHandler, true);
};
}, []);
return (
<div className="container">
<ul className="myMenu nav list-unstyled d-flex flex-nowrap fixed-top">
{list.map((item, i) => (
<li className="nav-item " key={i} ref={navRefs.current[i]}>
<a
href={`#s-${i}`}
className={`nav-link text-nowrap ${
active === i ? "text-danger" : ""
}`}
onClick={(e) => {
scrollTo(i);
}}
>
{item}
</a>
</li>
))}
</ul>
<ul className="mb-100 list-unstyled">
{list.map((item, i) => (
<li id={`s-${i}`} ref={scrollRefs.current[i]} className="py-100 px-3">
<h3>{item}</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi,
dicta.
</p>
</li>
))}
</ul>
</div>
);
}
Horizontal Scrolling on React Component Using Vertical Mouse Wheel
Okay, so the issue seems to be that you only refer to the function event.preventDefault
rather than invoking it.
Adding some brackets at the end to invoke it should do the trick:event.preventDefault()
.
I however found this issue while looking for some simple code to use, so I will also leave the hook I made for this if others in the same situation:
import { useRef, useEffect } from "react";
export function useHorizontalScroll() {
const elRef = useRef();
useEffect(() => {
const el = elRef.current;
if (el) {
const onWheel = e => {
if (e.deltaY == 0) return;
e.preventDefault();
el.scrollTo({
left: el.scrollLeft + e.deltaY,
behavior: "smooth"
});
};
el.addEventListener("wheel", onWheel);
return () => el.removeEventListener("wheel", onWheel);
}
}, []);
return elRef;
}
Usage:
import React from "react";
import { useSideScroll } from "./useSideScroll";
export const SideScrollTest = () => {
const scrollRef = useHorizontalScroll();
return (
<div ref={scrollRef} style={{ width: 300, overflow: "auto" }}>
<div style={{ whiteSpace: "nowrap" }}>
I will definitely overflow due to the small width of my parent container
</div>
</div>
);
};
Note:
The scroll behavior "smooth" seems to be giving some trouble when trying to do continuous scrolling. This behavior can be omitted to have proper continuous scrolling, but it will look jerky.
As far as I know, there is no easy solution for this. I have however created a rather involved solution in my own project, so thought some people may appreciate that also: https://gist.github.com/TarVK/4cc89772e606e57f268d479605d7aded
Horizontal scrolling with mouse wheel and button in a div
Thank you for anyone who paying attention to my problems. I have solved this by myself luckily. This is the answer how i solve it.
onWheel(event: WheelEvent): void {
this.widgetsContent.nativeElement.scrollLeft += event.deltaY;
event.preventDefault();
}
How to do a horizontal scroll on mouse wheel scroll?
It looks like he's just mapping the mousewheel event to scrolling the area. In IE, this is really easy by just using the doScroll()
method - this will scroll the horizontal bar by the amount the vertical bar would normally scroll by. Other browsers don't support the doScroll()
method, so you have to live with scrolling by an arbitrary amount instead:
var mouseWheelEvt = function (event) {
if (document.body.doScroll)
document.body.doScroll(event.wheelDelta>0?"left":"right");
else if ((event.wheelDelta || event.detail) > 0)
document.body.scrollLeft -= 10;
else
document.body.scrollLeft += 10;
return false;
}
document.body.addEventListener("mousewheel", mouseWheelEvt);
Related Topics
Tools for Obfuscating HTML and CSS
How Move 'Nav' Element Under 'Navbar-Brand' in My Navbar
Selecting All Links Except Hovered One CSS Only
CSS Stretch Textbox to Fill Remaining Space
Background Video with 100% Width and Fixed Height
How to Set The <Img> Tag with Basic Authentication
HTML5 Input Box with Type="Number" Does Not Accept Comma in Chrome Browser
How to Send HTML Email Using R
Why Does an Anchor Tag's Href Values Need Http:// Preprended to The Url
How to Detect "​" (Combination of Unicode) in C++ String
Jenkins Content Security Policy
Aligning Text on a Specific Character