power-cut
power-cut

Reputation: 1498

Click on div except the button - Vue

I have a simple div with width 100%, with a button in it.

Problem is that when I add a click event to the div, my complete div becomes clickable (including the button as well);

I would want to make the whole div clickable with a different method while the button click with another method.

<div class="full-width" @click="method1">
  <button @click="method2">click me</div>
</div>
<script>
export default {
methods: {
  method1() {
    console.log("div is clicked")
  },
  method2() {
    console.log("button is clicked")
  }
}
</script>

Upvotes: 0

Views: 1041

Answers (3)

hamid niakan
hamid niakan

Reputation: 2871

there are two ways to achieve this in vue way:

  1. you can use @click.self on the div and @click on the button
  2. you can use @click.stop on the button and @click on the div

the first approach tells the div to only listen for the events where the event target is itself and the second one tells the button to stop event propagation and therefore click event does not reach the div

edit: added both approach for the select element

check the demo below:

new Vue({
  el: '#app',
  data: () => ({
    msg1: '',
    msg2: '',
    msg3: '',
    msg4: '',
  }),
  methods: {
    method1(v) {
      this[v] = 'clicked on div';
    },
    method2(v, elm = 'button') {
      this[v] = `clicked on ${elm}`;
    }
  },
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<div id="app">
  <div style="border: 2px solid red; width: 100%" @click.self="method1('msg1')">
    <button @click="method2('msg1')">click me</button>
  </div>
  <div>{{ msg1 }}</div>

  <div style="border: 2px solid green; width: 100%; margin-top: 20px" @click="method1('msg2')">
    <button @click.stop="method2('msg2')">click me</button>
  </div>
  <div>{{ msg2 }}</div>

  <div style="border: 2px solid blue; width: 100%; margin-top: 20px" @click.self="method1('msg3')">
    <select @click="method2('msg3', 'select')">
      <option value="">--Please choose an option--</option>
      <option value="dog">Dog</option>
      <option value="cat">Cat</option>
      <option value="hamster">Hamster</option>
      <option value="parrot">Parrot</option>
      <option value="spider">Spider</option>
      <option value="goldfish">Goldfish</option>
    </select>
  </div>
  <div style="text-align: right">{{ msg3 }}</div>

  <div style="border: 2px solid orange; width: 100%; margin-top: 20px" @click="method1('msg4')">
    <select @click.stop="method2('msg4', 'select')">
      <option value="">--Please choose an option--</option>
      <option value="dog">Dog</option>
      <option value="cat">Cat</option>
      <option value="hamster">Hamster</option>
      <option value="parrot">Parrot</option>
      <option value="spider">Spider</option>
      <option value="goldfish">Goldfish</option>
    </select>
  </div>
  <div style="text-align: right">{{ msg4 }}</div>
</div>

Upvotes: 6

Tafita Raza
Tafita Raza

Reputation: 341

Just use @click.stop on the button and @click on the div. Like this :

<div class="full-width" @click="method1">
  <button @click.stop="method2">click me</div>
</div>

Upvotes: 1

Patric
Patric

Reputation: 11

this should do the trick.

<template>
  <div id="myDiv" @click="handleDivClick">
    <button id="myButton" @click="handleButtonClick">Click me</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleDivClick(event) {
      if (event.target.id === 'myButton') {
        // The button was clicked
        // Do something here
      } else {
        // The div was clicked, but not the button
        // Do something else here
      }
    },
    handleButtonClick() {
      // The button was clicked
      // Do something here
    },
  },
};
</script>

if it doesn't work i suggest you use vanilla javascript to implement this

Upvotes: 0

Related Questions