Press the div, excluding the button - Vue

I have a basic div that spans 100% of the width, containing a button inside.

The issue I'm facing is that when I add a click event to the div, the entire div becomes clickable (including the button within it).

What I want is for the whole div to be clickable with one method, while the button should trigger a different method when clicked.

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

Answer №1

Vue offers two different methods to achieve this functionality:

  1. You can utilize @click.self on the div element and @click on the button
  2. Alternatively, you can apply @click.stop on the button and @click on the div

The first approach instructs the div to only respond to events where the target is itself. On the other hand, the second method prevents event propagation on the button, ensuring that the click event does not propagate to the div

edit: included both techniques for handling select elements

Feel free to check out the demonstration 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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92fcffffdaf8c6ff">[email protected]</a>/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>

Answer №2

Give this a try, it should work like a charm.

<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') {
        // Button click logic
        // Implement your code here
      } else {
        // Div click logic
        // Implement another code here
      }
    },
    handleButtonClick() {
      // Button click logic
      // Implement your code here
    },
  },
};
</script>

If this doesn't solve the issue, I recommend using vanilla JavaScript for this implementation.

Answer №3

To ensure the button does not trigger the div's click event, use @click.stop on the button and bind @click to the div element. Here is an example:

<div class="full-width" @click="handleMethod1">
  <button @click.stop="handleMethod2">Click Me</div>
</div>

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

Get data from a JSON file using JavaScript

Dealing with a rather intricate and detailed JSON structure, I have a specific extraction task at hand. The goal is to retrieve information (text) from the JSON only if the resource-id includes the text "com.shazam.android:id/" and certain prope ...

VueJS 3 custom Checkbox fails to update UI upon clicking

I'm attempting to implement a customized checkbox using Vue 3 and the composition API based on this example. However, despite confirming through devtools that all my props and bound data are successfully passed from the parent component to the child c ...

How to pause a loop temporarily before proceeding with the next iteration

I am facing a challenge where I want to trigger two events simultaneously, but only one event should be allowed to continue at a time. If an event is already in progress, I need the ability to forcefully stop it and allow the other event to take control. S ...

When transitioning between single-page Angular applications using Protractor, a "JavaScript error: document unloaded while waiting for result" may be encountered

I came across this article discussing the issue of a Javascript error related to a document being unloaded while waiting for a result: JavascriptError: javascript error: document unloaded while waiting for result Although the solution provided seems to wo ...

When the button is clicked, request the total count of elements in the array

Is there a way to log the index of an array element when clicked? I have a large array with over 100 elements: var cubesmixed = []; var cubes; for(var i = 0; i < 143; i++) { cubes = paper.rect(Math.floor(Math.random()*2000), Math.floor(Math.random ...

display a dual-column list using ngFor in Angular

I encountered a situation where I needed to display data from an object response in 2 columns. The catch is that the number of items in the data can vary, with odd and even numbers. To illustrate, let's assume I have 5 data items to display using 2 co ...

What is the process of embedding base64 encoded data into an image in Javascript after retrieving the data from Azure Blob Storage?

I am attempting to insert an image by utilizing the base64 data pattern, rather than a URL link. Initially, I retrieve the data from Azure Blob storage using the Azure Node.js SDK: Azure Node.js SDK After downloading the data as a string, I am unsure of ...

Can you provide the regular expression that will successfully match this specific string of text?

Can you solve this fruit riddle? apple is 2kg apple banana mango is 2kg apple apple apple is 6kg banana banana banana is 6kg If the fruits are limited to "apple", "banana", and "mango", how can we write a regex that extracts the names of ...

Design a button for removing the selected value in select2

Can anyone provide some guidance on using select2? I am working with 2 select2 elements, and I want the selected value to be displayed on a button instead of in the input area of the select2. This way, the select2 will still display the placeholder text. ...

Is there a way to add 100 headings to a webpage without using a loop when the page loads

Just joining this platform, so please be patient with me! The task at hand is to insert 100 h3 headings on page load ("Accusation 1, Accusation 2, Accusation 3,...Accusation 100"). We are restricted to using only 1 loop throughout the lab, which will also ...

Exploring the Power of Observables in Angular 2: Focusing on Targeting an Array Nested Within

I encountered a situation where I was successfully looping through objects in an array within my Angular 2 application using observables. In the client service file, my code looked like this: getByCategory(category: string) { const q = encodeURICompon ...

Steps for refreshing Google reCAPTCHA on an AJAX-enabled webpage

I am encountering an issue with two captchas on my website. One captcha is loaded upon refresh, while the second captcha is loaded on a different page via ajax. The problem arises when I click on the "No" button after selecting it on the second page. I wan ...

Tips for looping through client.get from the Twitter API with node.js and express

I am in the process of developing an application that can download a specific number of tweets. For this project, I am utilizing node.js and express() within my server.js file. To retrieve data from the Twitter API, I have set up a route app.get('/ap ...

Node.js offers a simple and efficient way to retrieve screen resolution. By using

I am trying to retrieve the screen resolution using node.js, but the code snippets provided are not working as expected. var w = screen.width; var h = screen.height; The following code also did not work for me: var w = window.screen.width; var h = windo ...

Embed a function within a string literal and pass it to another component

Is there a way to pass a function defined in actions to an element? Reducer case 'UPDATE_HEADER': return Object.assign({}, state, { headerChildren: state.headerChildren.concat([action.child]) }); Action.js export const deleteH ...

The drop-down menu fails to appear when I move my cursor over it

#menu { overflow: hidden; background: #202020; } #menu ul { margin: 0px 0px 0px 0px; padding: 0px 0px; list-style: none; line-height: normal; text-align: center; } #menu li { display: inline-block; } #menu a { display: block; position: relative; padding ...

Can you tell me about the feature called "Inspect Browser" box?

Can you identify the significance of this enigmatic purple box while inspecting elements in the browser's developer tools? It does not correspond to padding, margins, or borders, yet it seems to be occupying space within the designated div. [1]: http ...

Angular - Clear the selection of <select><option> if I opt out of accepting the change

I have created a dropdown menu using HTML <select> and <option> tags, along with a JavaScript function that triggers a confirmation dialogue when an option is selected. The confirmation offers a simple choice between "yes" or "no." If the user ...

Type of result from a function that returns a linked promise

In my class, I have a method that returns a chained promise. The first promise's type is angular.IPromise<Foo>, and the second promise resolves with type angular.IPromise<Bar>. I am perplexed as to why the return type of doSomething is an ...

Leveraging the Composition API in Vue 3: Implementing reusable code from a separate file into the template

I have developed a reusable code snippet in dateTime.js: import { ref, computed, watch } from 'vue'; import * as dayjs from 'dayjs'; export default function dateTime() { const newDateTimeString = ref(null); function showDateT ...