Adjusting CSS properties according to scrolling position

Imagine a scenario where there are two hidden buttons - one on the right half and the other on the left half. The button on the right, when clicked, horizontally scrolls you to the next section, and the button on the left takes you back to the previous section. These buttons display left and right arrow cursors when hovered over, indicating the scroll direction.

The goal is to change the cursor of the goToPreviousSectionButton to default when scrollPosition === 0, and similarly for the goToNextSectionButton when

scrollPosition === maxScrollPosition
.

To simplify it: when you test the code snippet, hover your mouse cursor to the left of number 1. You will notice a left arrow cursor, but ideally, it should be a default cursor since you cannot go any further left from here. The same applies when you reach number 3, where the right arrow cursor should also switch to a default cursor as going any further is not possible.

I am facing difficulties in implementing this. Your assistance with this issue would be highly appreciated.


let scrollPosition = 0
const maxScrollPosition = document.body.scrollWidth - window.innerWidth

const goToPreviousSectionButton = document.createElement("button")
const goToNextSectionButton = document.createElement("button")

document.body.appendChild(goToPreviousSectionButton)
document.body.appendChild(goToNextSectionButton)

if (scrollPosition === 0) {
  // If scroll position is at the beginning
}

if (scrollPosition === maxScrollPosition) {
  // If scroll position at the end
}

goToPreviousSectionButton.addEventListener("click", () => {
  window.scrollBy(-window.innerWidth, 0)
})

goToNextSectionButton.addEventListener("click", () => {
  window.scrollBy(window.innerWidth, 0)
})
* {
  margin: 0;
  padding: 0
}

html { height: 100% }

html, body, main {
  display: flex;
  flex-grow: 1
}

section {
  display: grid;
  place-items: center;
  flex: 1 0 100%
}

section:nth-of-type(1) { background: orange }
section:nth-of-type(2) { background: limeGreen }
section:nth-of-type(3) { background: royalBlue }

h2 { color: white }

button {
  background: transparent;
  position: fixed;
  top: 0;
  width: 50%;
  height: 100%;
  border: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent
}

:focus { outline: none }

button:nth-of-type(1) { /* Left button */
  left: 0;
  cursor: w-resize
}
button:nth-of-type(2) { /* Right button */
  right: 0;
  cursor: e-resize
}
<main>
  <section>
    <h2>1</h2>
  </section>
  <section>
    <h2>2</h2>
  </section>
  <section>
    <h2>3</h2>
  </section>
</main>

Answer №1

If you want to enhance your website with additional elements without affecting the functionality of invisible buttons, one approach is to use pseudo-elements to cover them and prevent any actions from being triggered:

const previousButton = document.createElement("button")
const nextButton = document.createElement("button")

document.body.appendChild(previousButton)
document.body.appendChild(nextButton)

previousButton.addEventListener("click", () => {
  window.scrollBy(-window.innerWidth, 0)
})

nextButton.addEventListener("click", () => {
  window.scrollBy(window.innerWidth, 0)
})
* {
  margin: 0;
  padding: 0
}

html,body { height: 100% }

body, main {
  display: flex;
  flex-grow: 1
}

section {
  display: grid;
  place-items: center;
  flex: 1 0 100%
}

section:nth-of-type(1) { background: orange }
section:nth-of-type(2) { background: limeGreen }
section:nth-of-type(3) { background: royalBlue }

h2 { color: white }

button {
  background: transparent;
  position: fixed;
  top: 0;
  width: 50%;
  height: 100%;
  border: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent
}

:focus { outline: none }

button:nth-of-type(1) { /* Left button */
  left: 0;
  cursor: w-resize
}
button:nth-of-type(2) { /* Right button */
  right: 0;
  cursor: e-resize
}

/* Additional Elements */
main:before,
main:after{
  content:"";
  z-index:9;
  position:relative;
  flex: 1 0 50%;
}
main:before {
  margin-right:-50%;
}
main:after {
  margin-left:-50%;
}
/**/
<main>
  <section>
    <h2>1</h2>
  </section>
  <section>
    <h2>2</h2>
  </section>
  <section>
    <h2>3</h2>
  </section>
</main>

Answer №2

let currentPosition = 0;
if (currentPosition === 0) {
  backButton.classList.add('inactive')
}

if (currentPosition === maxScroll) {
  backButton.classList.add('inactive')
}

styles:

.inactive {
 cursor: not-allowed
}

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

Querying data with parameters in a client-side rendered application with Next.js

Currently, I am developing a chat application using Next.js and Axios. One of the functionalities I implemented is a dynamic route called chat/:pid to fetch data using the provided pid. However, I encountered an issue where the values are coming back as un ...

Illuminating Wireframes with Three.js MeshPhongMaterial

While attempting to display a mesh with Phong shading along with wireframe on an ArrayBufferGeometry where the vertex colors are set to THREE.vertexColors, I encountered an issue where the lighting only affects one random face. However, when I switch to Me ...

The border line beside the text in the current tab remains unchanged

I want to display a border line next to a tab when it is clicked or active. Currently, I am only able to show the line next to the tab that was initially selected, but it does not change dynamically with other tabs. Here is my current implementation: $(d ...

Page transitions spring boot program

I am encountering an issue when trying to navigate between pages. I have a button that triggers an AJAX POST request. Here is an example of the code: $.ajax({ contentType: "application/json", type: "POST", data: JSON.stringify(pro ...

Creating a unique WooCommerce product category dropdown shortcode for your website

I am having trouble implementing a WooCommerce categories dropdown shortcode. Although I can see the drop-down menu, selecting a category does not seem to trigger any action. Shortcode: [product_categories_dropdown orderby="title" count="0" hierarchical=" ...

Determine the number of elements chosen within a complex JSON structure

I need to figure out how to count the length of a jsonArray, but I'm stuck. Here's an example to start with: https://jsfiddle.net/vuqcopm7/13/ In summary, if you click on an item in the list, such as "asd1", it will create an input text every t ...

Change Observable<String[]> into Observable<DataType[]>

I'm currently working with an API that provides me with an Array<string> of IDs when given an original ID (one to many relationship). My goal is to make individual HTTP requests for each of these IDs in order to retrieve the associated data from ...

The node software indicates its version as v23.0.0-nightly2024071586415e4688

Attempting to update Node on UBUNTU (version 22.04.4 LTS) by following the official procedure provided on their site has led to unexpected issues: # installs nvm (Node Version Manager) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.s ...

Hover over ASP.Net within Visual Studio 2017

I have 3 images (1, 2, and 3) all sized at 100x100px, and image 4 which is 500x500px in size (with a default source of image1.jpg). When hovering over image 2 or 3, I want to display a larger view of the respective image at 500x500px. How can I achieve th ...

JavaScript/jQuery Tutorial: Accessing the src attribute of images sharing a common class名

How can I extract the src values of images with the same class and display them in an empty div? For instance: <body> <img class="class1" src="http://www.mysite.com/img/image1.jpg" width="168" height="168" alt=""> <img class="class ...

Having trouble with the input range slider on Chrome? No worries, it's working perfectly fine

I'm currently facing an issue with an input range slider that controls the position of an audio track. It seems to work perfectly in Firefox, but in Chrome, the slider gets stuck and doesn't move when dragged. There is a function in place that up ...

How to display information from a JSON file using dynamic routing in a React.js application

I'm currently working on a project to replicate Netflix using reactjs, but I've hit a roadblock and can't figure out what to do next. I've tried watching YouTube tutorials and reading articles online, but I haven't been able to fin ...

How can I stop popup labels from appearing in MapBox GL JS when I don't want them to be visible?

Having created an application using MapBox GL JS, I have placed numerous markers all around the globe. As the mouse hovers over these markers, a description box pops up, which is what I intended. However, I am encountering an issue where these labels flick ...

Exploring ways to utilize Vue data variables and methods within the configuration options of Tabulator

Utilizing tabulator in conjunction with vue using the following packages: tabulator-tables and vue-tabulator. In an attempt to implement a click event on the tabulator row, I am faced with the challenge of accessing vue data variables within the scope of ...

Tips for showcasing a changing placeholder message within the <v-text-field> component in Vuetify

Here is the code snippet representing a text field: <v-text-field v-model="input" placeholder="(0 - 200)"> </v-text-field> The Vue.js data section includes: export default { data () { return { input: '', propose ...

An array in JSON format containing only one element

I am currently working on a project that involves JSON format output. I am in need of some clarity regarding the structure of JSON arrays. Specifically, I'm curious about how to handle fields that allow multiple entries in an array format. In cases wh ...

Vue feature allows users to save favorite films

Welcome to my homepage where I showcase 3 movies taken from the store, each with an "add to fav" button. My goal is to have the selected movie appear on the favorites page when clicked. As a newcomer to Vue, any code or documentation suggestions would be h ...

Displaying information from a database in a text box

I'm trying to display data from a database in a textbox using this code. However, when I click the show button, I encounter an error: (Notice: Undefined index: first_name ) How can I successfully display the data in the textbox? **//BootStrap Co ...

What is the process for preventing the execution of APIs in Postman?

Currently, I am incorporating node js on my server side and I am in need of restricting the API from running on postman or any other platform besides a browser. Perhaps implementing a policy could be the solution, however, I am uncertain about how to go ...

How to create a transparent background image in a Jekyll theme without impacting the visibility of the foreground

I'm new to HTML and CSS, currently working with a Jekyll boostrap landing theme from GitHub to create a static responsive website. I'm looking to change the background image on the theme and make it transparent to enhance the visibility of the fo ...