Scroll horizontally on a webpage using drag with JavaScript

I have been working on a unique horizontal website design that allows users to scroll horizontally by dragging the screen. I managed to successfully implement the horizontal scrolling feature, but I am facing difficulties in adding the horizontal drag-to-scroll functionality. To clarify, this means users should be able to drag the screen horizontally to navigate the content. You can view an example of what I'm aiming for here.

Unfortunately, my JavaScript code does not seem to enable the dragging function as intended, although the scrolling works fine, as demonstrated in the example provided.

Here is the snippet of my code:

// script.js

const slider = document.querySelector('.wrapper');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', (e) => {
  if(!isDown) return;
  e.preventDefault();
  const x = e.pageX - slider.offsetLeft;
  const walk = (x - startX) * 3; //scroll-fast
  slider.scrollLeft = scrollLeft - walk;
  console.log(walk);
});
/* style.css */

.outer-wrapper {
  width: 100vh;
  height: 100vw;
  transform: rotate(-90deg) translateX(-100vh);
  transform-origin: top left;
  overflow-x: hidden;
  position: absolute;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.wrapper {
  display: flex;
  flex-direction: row;
  width: 400vw;
  transform: rotate(90deg) translateY(-100vh);
  transform-origin: top left;
  overflow: hidden;
  cursor: pointer;
}


.wrapper.active {
  cursor: grabbing;
  cursor: -webkit-grabbing;
}

.slide {
  width: 100vw;
  height: 100vh;
}

.one {
  background: #efdefe;
}
.two {
  background: #a3f3d3;
}
.three {
  background: #0bbaa0;
}
.four {
  background: #00dfdf;
}

::-webkit-scrollbar {
  display:none;
}

Answer №1

Appears to be an issue with the variable selection, make sure to choose outer and scrollTop instead of scrollLeft You can implement this solution:

var slider = document.querySelector('.wrapper');
var outer = document.querySelector('.outer-wrapper');
let isDown = false;
let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
  startX = e.pageX - slider.offsetLeft;
  scrollLeft = slider.scrollLeft;

  outer.scrollTop = startX;
});
slider.addEventListener('mouseleave', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
  isDown = false;
  slider.classList.remove('active');
});
slider.addEventListener('mousemove', (e) => {
  if(!isDown) return;
  e.preventDefault();
  const x = e.pageX - slider.offsetLeft;
  const walk = (x - startX) * 3; //scroll-fast
  slider.scrollLeft = scrollLeft - walk;
  slider.scrollLeft = startX;
  console.log(walk);
    outer.scrollTop = x;
});
.outer-wrapper {
  width: 100vh;
  height: 100vw;
  transform: rotate(-90deg) translateX(-100vh);
  transform-origin: top left;
  overflow-x: hidden;
  position: absolute;
}

.wrapper {
  display: flex;
  flex-direction: row;
  width: 400vw;
  transform: rotate(90deg) translateY(-100vh);
  transform-origin: top left;
  overflow-x: hidden;
  cursor: pointer;
}


.wrapper.active {
  cursor: grabbing;
  cursor: -webkit-grabbing;
}

.slide {
  width: 100vw;
  height: 100vh;
}

.one {
  background: #efdefe;
}
.two {
  background: #a3f3d3;
}
.three {
  background: #0bbaa0;
}
.four {
  background: #00dfdf;
}
::-webkit-scrollbar {
  display:none;
}
<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE-edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CodePen - GLTF Model Loading (.glb / .gltf)</title>
  <link rel="stylesheet" href="style.css">

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

</head>
<body id="homePage">



  <div class="outer-wrapper">
    <div class="wrapper">
      <div class="slide one"></div>
      <div class="slide two"></div>
      <div class="slide three"></div>
      <div class="slide four"></div>
    </div>
  </div>

<script src="sliderScript.js"></script>

</body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Enhance your web application with dynamic drop-down selection using Spring, Ajax

In my JSP file, I have a script that populates the list of states based on the selected country. The script fetches data from the controller and is supposed to display the list of states. However, after calling the controller method, the alert "received da ...

Is it possible to modify the numerical values within TimeCircles.js?

I have integrated the TimeCircles.js plugin into a Persian website and need to convert Persian numbers to English. I already have a function that replaces each digit with the appropriate English number. I am able to successfully convert the text inside t ...

Designing the Irish flag solely with HTML and CSS: a step-by-step guide

I have successfully created the Indian flag using HTML and CSS, with the exception of the Ashok Chakra. Now, I am looking to create the Irish flag which features a vertical tricolor design, unlike the horizontal tricolor layout of the Indian flag. Can anyo ...

What is the process for uploading a file using the client's file path?

I'm fascinated by the way Sonic Living is able to identify and upload your iTunes library XML file with such ease. Unlike other upload libraries I've explored, it prompts user approval before automatically uploading the XML file based on client O ...

"Caution: Refs cannot be assigned to function components" message encountered when utilizing a custom component in Next.js

I created a component called HeaderIcon with the following code: function HeaderIcon({ inactiveIcon, activeIcon }) { const [isActive, setIsActive] = useState(false); return ( <div onClick={() => setIsActive(!isActive)}> {isActive ? ...

Having difficulty comprehending the syntax of Linear Gradients

Seeking assistance on understanding how background images and linear gradients function together. Currently, I am only seeing a solid color instead of the intended image. Can someone please explain how this code is supposed to work? background-image:lin ...

What is the reason for me continuously receiving the error "cannot read map of undefined"?

Having trouble debugging my redux sagas and react integration. No matter what initial state I set, I keep running into undefined errors when trying to map through the data. I've tried null, undefined, and empty arrays but nothing seems to work. Can a ...

Having trouble with nested confirm pop ups?

I am attempting to show an additional confirmation pop-up when the YES button is clicked, but it doesn't seem to be working. Here's my code: $.confirm({ text: "Are you sure you want to delete ?", confirm: function() { $.confirm( ...

The getelementbyid function is unable to locate the specified button identifier

As I dive into the world of Javascript, I wanted to create a simple input form with a corresponding response field on my website. However, I encountered an issue where using a basic submit button caused the page to refresh and erase the textfields before ...

The jQuery window.load() function fails to execute on iOS5 devices

I added a basic loading div to my website that fades out once the entire page has finished loading. The code I used is simple: $(window).load(function(){ $('#loading').fadeOut(500); }); While this works well on all desktop browsers and Chro ...

Tips for automating the activation of intents at specific scheduled times in Dialogflow

I'm attempting to automatically trigger intents in Dialogflow to obtain the user's contact details at a scheduled time. Is it possible to achieve this using JavaScript? If so, could you please provide the code? ...

The web service that retrieves XML data using jQuery functions perfectly on a local environment, but faces issues when deployed to

I have a webmethod that returns data. I am using jQuery to call this function with its Content type specified as XML. The interesting issue is that it works fine on my local machine but not on the server. Here is the code snippet I am currently using: var ...

An issue with the AngularJS [$parse:syntax] error has been identified when using specific data in the

I encountered an issue when attempting to create an AngularJS ui-grid table with data that includes a '(' and then whitespace before the closing ')' within a string. This resulted in an AngularJS error message: Syntax Error: Token &a ...

Is there a way to monitor and trigger a function in jQuery when a loaded PHP file is modified?

I am currently working on a dynamic dashboard that automatically updates every few seconds to display new information fetched from a PHP file. My goal is to trigger an alert only when there is a change in the data itself, rather than just a refresh. In ord ...

Grabbing only the button element using jQuery when a click event occurs

HEY THERE! I have a simple question that I need help with. To better explain the issue, I've included a small code snippet below. The problem I'm facing is related to grabbing the id of a button. Everything works fine except when I click on any ...

Having trouble with the CSS `not` selector?

Below is the code snippet I experimented with XHTML <div> <span>Span1</span> <span>Span12</span> <span>Span13</span> </div> <div> <span>Span1</span> <span> ...

Tips on formatting text as bold or italic when tweeting from my website to our Twitter account

Currently, I am utilizing the Twitter OAuth library in conjunction with PHP to publish a tweet from my website directly to my Twitter account. My main objective is to highlight some text while posting, however, I have not been successful in identifying t ...

What is the proper way to bind CoreUI's CSwitch component?

I am trying to incorporate the CSwitch component into a DevExtreme data grid. While the DxSwitch component functions correctly, I am unable to get the CSwitch to work properly. It seems like I might be using the wrong binding. Could that be the issue? < ...

"Complete with Style: Expand Your Horizons with Material-UI

The Autocomplete feature in Material UI is not expanding to the full width of the TextField element. Any suggestions on how to fix this issue? https://i.sstatic.net/3ccdp.png https://i.sstatic.net/KdkrO.png ...

The swf file doesn't stretch to fit the window when the height is set to 100%

Struggling with creating a flash recorder controlled by JavaScript? Trying to get the flash to fill the browser window but disappearing when setting height or width to 100%? Where am I going wrong? <div id="flashrecorder"> <object wmode="trans ...