html - Vue.js 图像映射单击后禁用区域

标签 html vue.js vuejs2 imagemap

我有一张包含 3 个区域的图像。当我单击每个区域时,我希望出现一系列问题。我已经这样做了,但我想稍微改变一下。 由于我不想将其重定向到页面,因此我将 # 作为 href 链接提供,并根据 event.currentTarget.id 获取该区域的 id 然后我有三个 v-if,每个组件都有一个条件。

这是jfiddle: https://jsfiddle.net/rau4apyg/

<div id="app">

<img id="Image-Maps-Com-image-maps-2017-03-16-100553" src="http://www.image-maps.com/m/private/0/fdfutap3klci37abfmuasc2mk7_screenshot.png" border="0" width="588" height="414" orgWidth="588" orgHeight="414" usemap="#image-maps-2017-03-16-100553" alt="" />
<map name="image-maps-2017-03-16-100553" id="ImageMapsCom-image-maps-2017-03-16-100553">
<area shape="rect" coords="586,412,588,414" alt="Image Map" style="outline:none;" title="Image Map" href="http://www.image-maps.com/index.php?aff=mapped_users_0" />
<area  id="component1" alt="" title="comp1" href="#" shape="poly" coords="420,228,296,34,180,226,178,228" style="outline:none;" target="_self" v-on:click="compId($event)"    />
<area  id="component2" alt="" title="comp2" href="#" shape="poly" coords="92,368,176,234,292,234,294,368,298,236,290,368" style="outline:none;" target="_self" v-on:click="compId($event)"     />
<area  id="component3" alt="" title="comp3" href="#" shape="poly" coords="506,366,296,366,296,232,422,232" style="outline:none;" target="_self" v-on:click="compId($event)"    />
</map> 
<h1> Title here </h1>
  <div v-if="compid === 'component1'"> 
  component1 is clicked, questions are shown 
  </div>
    <!-- show questions in for loop -->

    <div v-if="compid === 'component2'">
      2 is clicked
    </div>
    <div v-if="compid === 'component3'">
      3 is clicked
    </div>
    <div v-show="questionIndex === quiz.questions.length -1"> 
    <button v-on:click="addAnswers">
        submit
      </button> 
    <h2>
    Quiz finished, plase continue with Component 2 questions. 
  </h2>
  <button v-on:click="goToNextComponent">
    Next
  </button> 
</div>
new Vue({
  el: '#app',
  data: {
    quiz: {
      questions: [],
      answers: []
    },
    // Store current question index
    questionIndex: 0,
    total:0,
    show: true,
    compid: '',
    flag: false
  },
  mounted: {
  //functions here
  },
  computed: {
    //functions here
  },
  // The view will trigger these methods on click
  methods: {
    //some functions

    //return id of clicked component
    compId: function(event){
      this.compid = event.currentTarget.id;
      console.log(event.currentTarget.id); // returns the name of the id clicked.
    } ,
    addAnswers: function(){
        //store answers in Firebase    
    //vm.$forceUpdate();
    flag = true; //change the flag
    console.log(flag);
    },
    goToNextComponent: function(){
    }
}
});

我想按顺序完成问题,即:先做 Component1 的问题,点击提交保存答案,然后显示 Component2 的问题,回答问题,然后转到 Component3。

如果用户完成了组件 1,我希望他无法再次回答这些问题,以某种方式禁用它,然后转到组件 2。 当他完成下一个组件时,我也想禁用它并转到最后一个组件。

我不知道如何让它以这种方式工作。我有两个想法: 1)当我单击提交按钮时,我将标志更改为 true。所以我知道组件 1 已被单击,并将其添加到 v-if 子句中。我尝试使用 && 运算符添加它,但它不起作用。 2) 提交后有一个“下一步”按钮(我不确定这听起来是否正常),单击该按钮时,显示组件 2 中包含的下一个问题。

P.S.我的数据库位于 Firebase 上,我将所有问题都存储在一个数组中。例如前 10 个问题是关于组件 1 的,接下来的 8 个问题是关于组件 2 的,等等。也许添加一个字段来分隔它们会更好吗?现在是这样的:

{
  "questions" : [ {
    "q_options" : [ "Yes", "No", "Don't know" ],
    "q_text" : "Do you agree with blah blah?"
  }}

也许我可以添加一个组件选项:1 您有什么建议可以解决这些问题吗?

最佳答案

我稍微修改了你的方法。本质上你走在正确的轨道上;您只需要跟踪已完成哪些问题即可。然后,当有人单击特定图像映射时,检查该操作是否已完成,如果是,则阻止导航到该图像映射。

const quiz = new Vue({
  el: '#app',
  data: {
    quiz: {
      questions:  [
        {
          "q_options" : [ "Yes", "No", "Don't know" ],
          "q_text" : "Do you agree with blah blah?",
          coords:"420,228,296,34,180,226,178,228",
          shape:"poly",
          completed: false,
          answer: null
        },
        {
          "q_options" : [ "Yes", "No", "Don't know" ],
          "q_text" : "Question Number 2?",
          coords:"92,368,176,234,292,234,294,368,298,236,290,368",
          shape: "poly",
          completed: false,
          answer: null
        },
        {
          "q_options" : [ "Yes", "No", "Don't know" ],
          "q_text" : "Question Number 3?",
          coords:"506,366,296,366,296,232,422,232",
          shape:"poly",
          completed: false,
          answer: null
        }],
      answers: []
    },
    currentQuestion: null,
    quizCompleted: false
  },
  methods: {
    selectQuestion(question){
      if (!question.completed)
        this.currentQuestion = question;
      else
        alert("This question has already been completed!")
    },
    completeQuestion(){
      this.currentQuestion.completed = true;
      let currentIndex = this.quiz.questions.indexOf(this.currentQuestion); 
      if ( currentIndex === this.quiz.questions.length - 1){
          this.quizCompleted = true;
          this.currentQuestion = null;     
          this.quiz.answers = this.quiz.questions.map(q => q.answer)
      } else {
        this.currentQuestion = this.quiz.questions[++currentIndex];
      }
    }
  },
  mounted(){
    this.currentQuestion = this.quiz.questions[0]
  }
});

模板:

<div id="app">
  <img id="Image-Maps-Com-image-maps-2017-03-16-100553" src="http://www.image-maps.com/m/private/0/fdfutap3klci37abfmuasc2mk7_screenshot.png" border="0" width="588" height="414" orgWidth="588" orgHeight="414" usemap="#image-maps-2017-03-16-100553" alt="" />
  <map name="image-maps-2017-03-16-100553" id="ImageMapsCom-image-maps-2017-03-16-100553">
    <area v-for="question in quiz.questions" 
          :shape="question.shape" 
          :coords="question.coords"
          @click="selectQuestion(question)"/>
  </map> 
  <div v-if="currentQuestion">
    <h1> {{currentQuestion.q_text}} </h1>
    <template v-for="(option, index) in currentQuestion.q_options">
      <input type="radio" :value="option" v-model="currentQuestion.answer">
      <label>{{option}}</label> 
      <br />
    </template>
    <button @click="completeQuestion">Complete</button>

  </div>
  <div v-if="quizCompleted">
    <h1>You're Done!</h1>
    {{quiz.answers}}
  </div>
</div>

这是一个工作 example .

一些要点。

  • 您的 map 区域似乎与问题直接相关,因此我只是将它们设为数据。然后您可以迭代它们来制作图像映射。当您想重复使用 Vue 进行不同的测验时,这将使事情变得更容易。
  • 您并不真的想显示和隐藏您所谓的“组件”。只需构建一个代表当前问题的模型并更改其数据即可。一般来说,在 Vue 中,您希望通过数据来驱动界面。

这尚未完善,但它实现了您的主要目标;使用 map 进行导航,并阻止导航到已完成的问题。

关于html - Vue.js 图像映射单击后禁用区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43232839/

相关文章:

PHP 日程表头

javascript - VueJS 2 值绑定(bind)中的条件渲染

javascript - 在 Parent 和 Grandchildren Vue 2 之间使用同步修饰符

html - 具有绝对位置的不同分组中的 z-index 子 div

javascript - 单击按钮时水平滚动

javascript - Vue/Nuxt/Vuex - [NUXT :SSR] [ERROR] [vuex] unknown getter

vuejs2 - 使用 VueJS 从表中删除行

node.js - Vue - 发布 .vue 文件或编译组件更好?

css - Bootstrap代码设计修改

javascript - Firebase 函数返回 "Response is not valid JSON object."