Mohd Ali
Mohd Ali

Reputation: 145

Unable to implement horizontal scrollbar plugin

I am using a color swatch plugin, here, which defines a custom Vue element.

I also followed this example to implement a JavaScript-baed scrollbar.

My .vue file is as follows:

<script> element:

export default {
  name: "ProjectTask",
  data: function() {
     return { } 
 },
 methods:
    .
    .
    .
    .
  ,
  mounted() {
    const rightBtn = document.querySelector('#right-button');
    const leftBtn = document.querySelector('#left-button');

    rightBtn.addEventListener("click", function(event) {
       const conent = document.querySelector('#content');
       conent.scrollLeft += 300;
       event.preventDefault();
    });

    leftBtn.addEventListener("click", function(event) {
      const conent = document.querySelector('#content');
      conent.scrollLeft -= 300;
      event.preventDefault();
    });
  }
}

<templete> element:

  <div class="leftScroll" >
     <button id="left-button"> swipe left </button>
  </div>  
  <div class="ColorsWraper2 col-lg-8" id="content">
          <swatches v-model="Project.color" :colors="color_picker" shapes="circles" inline></swatches>
  </div>
  <div class="rightScroll">
     <button id="right-button"> swipe right </button>
  </div>

<style> element:

.ColorsWraper2 {
  white-space: nowrap;
  overflow-x: hidden;
  overflow-y: hidden;
}

The plugin's components should appear between the two buttons (left/right).

But, it does not work for me!

Upvotes: 0

Views: 145

Answers (1)

NBTX
NBTX

Reputation: 606

I'm assuming you mean you want to center the color swatches between the buttons - which I've done by using CSS Flexbox (Can I Use: CSS Flexbox).

If you want to understand exactly what I did, and why, check out the steps below. Otherwise skip forward to the code examples section where I briefly comment on what I did.


Step 1: Activate CSS flexbox

  • I wrapped the entire slider that you have in your <template>, in a div, .scroll-slider.
  • Next, I set this to use flex, display: flex and set the flex-direction: row.
  • A crucial part of this step was to set align-items: center which vertically aligned the items (noticeably the buttons) in the middle and prevented the buttons from filling the height.

Step 2: Prevent overflow (and wrapping) on the color swatch.

There were two parts to this step.

  1. Remove overflow on the external wrapper .colors-wrapper - this is as simple as overflow: hidden;. You should add margin and padding to the external wrapper as this will result in more accurate (desired) results when resizing.

  2. Prevent overflow on the inner wrapper, .colors-wrapper-inner. This is where I used your method of removing the overflow and wrapping:

.colors-wrapper-inner {
    white-space: nowrap;
    overflow: hidden;
}

Step 3: Fix button sizing.

  • At this point, you may have noticed that the buttons have been squished - which usually looks quite weird... Fortunately, the easy fix is just disabling flex-shrink with flex-shrink: 0.

Code Examples

JSFiddle: https://jsfiddle.net/SamJakob/st45o0kb/

StackOverflow Snippet:

// This is equvilent to import (using this because JSFiddle doesn't support npm)
Vue.component('swatches', VueSwatches.default);

new Vue({
  name: "ProjectTask",
  el: "#app",
  data() {
    return {
      color: "#1CA085"
    }
  },
  methods: {

    swipeRight: function() {
      const content = document.querySelector('#content');
      content.scrollLeft += 300;
    },

    swipeLeft: function() {
      const content = document.querySelector('#content');
      content.scrollLeft -= 300;
    }

  },
  mounted() {
    const rightBtn = document.querySelector('#right-button');
    const leftBtn = document.querySelector('#left-button');
  }
})
/* General Styles - please ignore */

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}


/* Wrapper styling */

.scroll-slider {
  /* Step 1: Setup a flexbox in the row-direction. */
  display: flex;
  flex-direction: row;
  /* This aligns the elements in the center
      (and prevents the buttons being full height) */
  align-items: center;
}

.colors-wrapper {
  /* Step 2.1: Make sure the swatches wrapper doesn't show any overflow. */
  overflow: hidden;
  /* An extra touch; add some margin around the color swatches. */
  margin: 0 10px;
}


/* Step 2.2: Make sure the inner swatches wrapper doesn't overflow */

.colors-wrapper-inner {
  white-space: nowrap;
  overflow: hidden;
}


/* Step 3: Make the buttons display at their normal size. */

.scroll-button-wrapper {
  /* This means the buttons won't shrink - which is why this works. */
  flex-shrink: 0;
}
<!-- Imports - please ignore -->
<link href="https://unpkg.com/[email protected]/dist/vue-swatches.min.css" rel="stylesheet" />
<script src="https://unpkg.com/[email protected]/dist/vue-swatches.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<!-- This would go inside your <template> element. -->
<div id="app">
  <div class="scroll-slider">

    <div class="scroll-button-wrapper">
      <!-- You can use the '@click' property to bind a method to the click event.  -->
      <button class="scroll-button" id="left-button" @click="swipeLeft"> swipe left </button>
    </div>

    <div class="colors-wrapper">

      <div class="colors-wrapper-inner" id="content">
        <swatches v-model="color" shapes="circles" inline></swatches>
      </div>

    </div>

    <div class="scroll-button-wrapper">
      <button class="scroll-button" id="right-button" @click="swipeRight"> swipe right </button>
    </div>

  </div>
</div>

Upvotes: 2

Related Questions