Navigating horizontally with buttons in VueJS

I am searching for a way to implement horizontal scrolling using buttons in VueJS. The idea is to have a container with multiple divs arranged horizontally, and I wish to navigate through them using the buttons.

If you want to see a similar solution using JQuery, you can check out this thread on SO. Also, here's a demo showcasing the desired effect in JQuery.

Is there a way to achieve this effect using VueJS?

I've already looked into a couple of libraries such as vue-scroll-to and jump.

  • Vue-scroll-to requires specifying an element to scroll to, but I need to scroll horizontally within a specific element by a fixed number of pixels.

  • Jump allows vertical scrolling over a set amount of pixels and seems to only work on the window.

UPDATE: I came across a small library that solves this issue using VanillaJS: https://github.com/tarun-dugar/easy-scroll

Answer №1

Take a look at the sandbox I created for this: sandbox link

Here is how the logic works:

scroll_left() {
  Use this function to scroll left by reducing the scrollLeft property value.
},
scroll_right() {
  Use this function to scroll right by increasing the scrollLeft property value.
}

In this implementation, you manipulate the scrollLeft property of a wrapper element.

If you want to see the complete code, click on this link: full code here

Answer №2

For those seeking a horizontal smooth scroll animation in vanilla JavaScript without relying on any external library, you can achieve it using the scrollTo method with behavior: 'smooth'.

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
el: '#app',

data: {
  scrollAmount: 0,
},

methods: {
scrollLeft: function () {
      const menu = this.$refs.menu
       menu.scrollTo({
      left: this.scrollAmount += 200,
      behavior: 'smooth',
    })
    },

scrollRight: function () {
      const menu = this.$refs.menu
       menu.scrollTo({
      left: this.scrollAmount -= 200,
      behavior: 'smooth',
    })
    }
},
mounted() {}
})
body {
    margin: 3em;
}

* {
    padding: 0;
    margin: 0;
} 

.menu-wrapper {
    position: relative;
    max-width: 310px;
    height: 100px;
    margin: 1em auto;
    border: 1px solid black;
    overflow-x: hidden;
    overflow-y: hidden;
}

.menu   {
  height: 120px;
  background: #f3f3f3;
  box-sizing: border-box;

  white-space: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
}
    
.item {
    display: inline-block;
    width: 100px;
    height: 100%;
    outline: 1px dotted gray;
    padding: 1em;
    box-sizing: border-box;
}

 
.paddle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 3em;
}
.left-paddle {
    left: 0;
}
.right-paddle {
    right: 0;
}
.hidden {
    display: none;
}

.print {
  margin: auto;
  max-width: 500px;
}
    
span {
    display: inline-block;
    width: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="menu-wrapper">
   <ul class="menu" ref="menu">
    <li class="item">1</li>
    <li class="item">2</li>
    <li class="item">3</li>
    <li class="item">4</li>
    <li class="item">5</li>
    <li class="item">6</li>
    <li class="item">7</li>
    <li class="item">8</li>
    <li class="item">9</li>
    <li class="item">10</li>
    <li class="item">11</li>
    <li class="item">12</li>
    <li class="item">13</li>
  </ul>
  
    <div class="paddles">
    <button class="left-paddle paddle" @click="scrollRight"> -
        </button>
      
        <button class="right-paddle paddle" @click="scrollLeft">
          >
        </button>
  </div>
  
</div>

Answer №3

By utilizing JavaScript alone, I have successfully converted the example you provided into a JavaScript-only format. Here is the Codepen link where you can view the code in action:

https://codepen.io/immad-hamid/pen/yEmayr

This JavaScript code can effectively replace the original example you shared:

const rightBtn = document.querySelector('#right-button');
const leftBtn = document.querySelector('#left-button');
const content = document.querySelector('#content');

rightBtn.addEventListener("click", function(event) {
  content.scrollLeft += 300;
  event.preventDefault();
});

leftBtn.addEventListener("click", function(event) {
  content.scrollLeft -= 300;
  event.preventDefault();
});

If you wish to incorporate animations, it would require implementing additional functionalities. Are you able to handle that?

Answer №4

Here's an example I found on codepen

$ Check out the link https://codepen.io/wa23/pen/pObyrq

Key points to note are:

HTML (pug)
link(href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400" rel="stylesheet")

h1 Vue Carousel
script#v-carousel(type="x/template")
  .card-carousel-wrapper
    .card-carousel--nav__left(
      @click="moveCarousel(-1)"
      :disabled="atHeadOfList"
    )
    // More HTML code here...
    
#app 
  carousel

CSS (Scss)

JS

Note: Apologies for the delayed response, been swamped with work lately.

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

Use Vue.js to display a class when the input is invalid and not empty

How can I apply a has-error class when an input is invalid and not empty in vue.js? <div class="form-group"> <input type="email" id="loginEmail" name="loginEmail" v-model="loginEmail" required> <label for="loginEmail">Email</label ...

Node.js utilized for conducting anti-virus scans on server-bound files prior to uploading

Is there a way for me to scan files that are submitted as request payloads to check if they contain potential viruses? For example, if someone tries to upload a txt file with the EICAR virus signature, I want to be able to scan it and reject it if it is in ...

AngularJS function orderBy reverses the array instead of sorting it

I encountered an issue where, after clicking the 'order button', the table does not order as expected. Instead, it reverses all the td elements. For example, 'A', 'C', 'B' becomes 'B', 'C', "A". I ...

Add at the beginning of each row in the text area

I have a small text area on my webpage where I want to add ">>" to the beginning of each line. My initial attempt was to use this code: $("#mytextarea").prepend("EvilHacker001>>"); Unfortunately, this did not produce the desired result. I se ...

Tips on adjusting the label size of a radar chart in chart.js

My radar chart labels are appearing skewed and messed up on mobile devices, so I decided to scale them using the following code within ComponentDidMount(): const plugins = [{ beforeDraw: function(c) { var chartHeight = c.chart.height; c ...

Trouble arises with AJAX due to DOM traversal errors

I am trying to set up a system for liking and disliking with a counter. However, I am facing issues with my AJAX call, specifically when attempting to change the HTML of selected elements in the view after sending values to the DB. The element in question ...

Using an iframe containing a link to trigger the opening of a colorbox in the

Recently, I encountered a challenge regarding an iframe containing a bar graph. I wanted to achieve that when the graph is clicked, it would open a colorbox with a more detailed graph from the "PARENT" of that iframe. Initially, I managed to get the ifram ...

"Caution: The `className` property did not align" when configuring a theme provider within Next.js

I'm currently working on developing a theme provider using the Context API to manage the application's theme, which is applied as a className on the body element. The implementation of the context is quite straightforward. When initializing the ...

What methods can be used to protect (encrypt using Java code) the information in a login form before it is sent to a servlet for

One major concern I have involves sending encrypted data (encrypted before sending the request) to a servlet. I attempted to call a function that encrypts passwords as an example, but I encountered difficulty passing values from JavaScript to Java code in ...

A guide on effectively mocking a Vuex store within the parentComponent of VueJS test-utils

I am currently using Jest in conjunction with vue-test-utils to test the reaction of a child component to an $emit event triggered by the parent component. The VueJS test-utils library offers a parentComponent option that can be utilized when mounting or ...

Page rotates on hover effect with RotateY

How can I get an image to rotate on the Y axis when hovered over? My code works in -moz- but not in -webkit- or -o-. What am I missing? .spin-logo { height: 450px; margin: 0 auto; -moz-transition: transform 2000ms ease 0s; -o-animation: transfor ...

What is the reason behind Firefox failing to display a linear gradient when the background-size values are more than 255px?

I am working on creating a grid overlay using an absolutely positioned non-interactive div. My approach involves using the repeating-linear-gradient property as suggested by others for this purpose. The functionality works smoothly in Chrome, but I seem to ...

The extent of the modal window (AngularJS directive)

I've been experimenting with a modal window feature using Angular UI Bootstrap. Within the parent controller, I've defined the following function: $scope.open = function () { var modalInstance = $modal.open({ templateUr ...

I'm having trouble retrieving the sessionid while using vue-cookies

Attempting to retrieve the sessionid from a cookie using vue-cookies. After importing vue-cookies, I checked and printed the cookies: import VueCookies from 'vue-cookies'; Vue.use(VueCookies); console.log(Vue.cookies.keys()); Despite seeing bo ...

How can I dynamically assign ng-model with a filter for a particular object in an array?

Is there a recommended method for linking an input element to a specific field of an object in an array using its id? I tried using ng-model along with the find() function from the array prototype. However, the implementation is not working properly as it ...

What steps can be taken to resolve the deprecated error for isVueInstance in vue.js2?

Utilizing vue-jest for test cases in vue.js2 involves working with a component named Register.vue. The test cases are written in Register.spec.js, and when running npm t, everything is functioning correctly. However, there are some errors being encountered ...

How can I set the width of a container dynamically using the Next JS Image component?

I have a situation where I am trying to set the height of an image within a container div to be equal to 100% of the container's height, while allowing the width of the container to adjust based on the image's aspect ratio. When using a standard ...

The tip display script is unable to revert back to its original content

I managed to show a block of text in a td after a mouseover event, but I want to revert back to the original content on mouseout/mouseleave. The code I used is below. Please help. I am getting an undefined error when running the code. I suspect the issue l ...

Transforming jQuery code to pure vanilla Javascript

For my project, I decided to convert my jQuery code into native JavaScript. The goal is to eliminate the dependency on jQuery and achieve the same functionality. The current setup involves two pages - page.html and side.html. The page.html document fetches ...

Experiencing issues with transferring JSON response from Axios to a data object causing errors

When I try to assign a JSON response to an empty data object to display search results, I encounter a typeerror: arr.slice is not a function error. However, if I directly add the JSON to the "schools" data object, the error does not occur. It seems like th ...