Home > Blockchain >  Click on image to show next image in array - vue blogpost with modal
Click on image to show next image in array - vue blogpost with modal

Time:12-06

I'd like to add a function to my blogposts where I can click an image and it'll automatically jump to the next image AND text.

I have made a simplistic version without the blog's structure, that works. Like so: https://i.gyazo.com/81c5baa0348518fd3327c303dac07dfc.mp4

But when I try to modify it to my blog's (Vue) structure, it won't work anymore, what am I doing wrong? I even tried some code I found on stack.

The commented out code is my own original code.

Follow-up question, how would I loop through text? Same way? At first glance I can't think of how.

HTML

<div id="app">
  <h1>Test pics</h1>
  <div> 
    <!--<img v-bind:src="images[hovered]" v-on:click="changePicture()" width="100px">-->
    <img v-if="image" :key="image" @click="changePicture"  :src="image" alt="image">
  </div>
</div>

Vue/Js

new Vue({
  el: "#app",
  data() {
    return {
    image:null,
    posts: [
      {
        id:1,
        hovered: 0,
        images: ['https://via.placeholder.com/150/0000FF/FFFFFF?text=1','https://via.placeholder.com/150/0000FF/FFFFFF?text=2','https://via.placeholder.com/150/0000FF/FFFFFF?text=3'],
        text: ['text=1','text=2','text=3']
      },
      {
        id:2,
        hovered: 0,
        images: ['https://dummyimage.com/600x400/f00/fff','https://dummyimage.com/600x400/00f/fff','https://dummyimage.com/600x400/fbh/fff'],
        text: ['dummy=1','dummy=2','dummy=3']
      }]
  };
  },
  mounted(){
    this.changePicture();
  },
  methods: {
    changePicture() {
      this.post.hovered = this.post.images[this.post.hovered];
      this.post.hovered = (this.post.hovered   1) % this.post.images.length;

      /*this.post.hovered = (  this.post.hovered)%(this.post.images.length);
      console.log(this.post.hovered 1);*/
    }
  }
})

EDIT:

The code that works: https://codepen.io/TCGPlaza/collab/QWxJXbp/01272374f7f79eb5efdd4bfcb2bb93f3

I want the working code to basically be replicated for multiple separate posts. Say I make a new post and I add 6 images, then all I have to do is click the image 6 times to make it back to the first image. Other posts might only have 2 images etc...

CodePudding user response:

If I understood you correctly try like following snippet:

First in mounted hook fill images array with objects that contains image, text and index number of image for every element of posts.images array)

In method changePicture pass index, check if nr is lower then images array length, then if it is increment it or if is not start from index 0.

Finally update your images array.

new Vue({
  el: "#app",
  data() {
    return {
      images:[],
      posts: [{id:1, hovered: 0, images: ['https://via.placeholder.com/150/0000FF/FFFFFF?text=1','https://via.placeholder.com/150/0000FF/FFFFFF?text=2','https://via.placeholder.com/150/0000FF/FFFFFF?text=3','https://via.placeholder.com/150/0000FF/FFFFFF?text=4','https://via.placeholder.com/150/0000FF/FFFFFF?text=5'], text: ['text=1','text=2','text=3','text=4','text=5']}, {id:2, hovered: 0, images: ['https://dummyimage.com/600x400/f00/fff','https://dummyimage.com/600x400/00f/fff','https://dummyimage.com/600x400/fbh/fff'], text: ['dummy=1','dummy=2','dummy=3']}]
    };
  },
  mounted(){
    this.posts.forEach(p => this.images.push({img: p.images[0], text: p.text[0], nr: 0}));
  },
  methods: {
    changePicture(idx) {
      let nr = this.images[idx].nr
      if (nr   1 < this.posts[idx].images.length) {
        nr   
      } else {
        nr = 0
      }
      this.images[idx].img = this.posts[idx].images[nr]
      this.images[idx].text = this.posts[idx].text[nr]
      this.images[idx].nr = nr
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h1>Test pics</h1>
  <div v-for="(post, idx) in posts" :key="idx"> 
    <img @click="changePicture(idx)"  :src="images[idx]?.img" alt="image" width="100px">
    {{ images[idx]?.text }}
  </div>
  {{images}}
</div>

  • Related