Interacting with a card in vuejs won't trigger any action

Is there a way to make an overlay disappear when clicking anywhere on the screen except for a specific card positioned on top of it? The current setup makes the overlay disappear even when the card is clicked. How can this behavior be corrected?

<div v-if="displayOverlay" class="overlay" @click="!displayOverlay">
  <div class="card"> Hello </div>
</div>

.card{
 position: absolute;
 bottom: 400px;
}

Answer №1

click event bubbles.

When a click event is triggered on <Child /> within this hierarchy:

<GrandParent>
  <Parent>
    <Child />
  </Parent>
</GrandParent>

, the event will propagate through each element in the following order 1:

  • on Child
  • on Parent
  • on GrandParent
  • ... and so on, up the DOM tree to the window.

To stop an event from bubbling further, you can use the stopPropagation method. This can be done at any level since events are fired sequentially, not simultaneously.

If you want to prevent the propagation to parents and block any subsequent event handlers on the current element, you need to call stopImmediatePropagation method on the event.

Vue offers event modifiers which simplify the process of calling native event methods.

In your scenario, you can use the .stop modifier on .card to prevent the event from reaching .overlay:

<div v-if="displayOverlay" class="overlay" @click="displayOverlay = false">
  <div class="card" @click.stop> Hello </div>
</div>

Demo 2, 3:

new Vue({
  el: '#app',
  data: () => ({
    displayCard: true
  })
})
.overlay {
  position: absolute;
  background-color: rgba(0,0,0,.21);
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.card {
  height: 200px;
  width: 300px;
  padding: 1rem;
  background-color: white;
}
body {
  margin: 0;
}
#app {
 min-height: 100vh;
}
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0c6c5d5f0829e869e8184">[email protected]</a>/dist/vue.min.js"></script>
<div id="app" @click="displayCard = true">
  <div class="overlay" v-if="displayCard" @click.stop="displayCard = false">
    <div class="card" @click.stop>Test</div>
  </div>
  <button v-if="!displayCard">Reopen overlay</button>
</div>

NOTES:

1 - The ordering mentioned above represents the default firing sequence. Vue provides a modifier (.capture) that allows you to modify it. Before executing the native sequence, Vue checks all parents (from window down to the clicked element) and if any of them has the .capture modifier, their event handler will run first (before the children's handlers). However, this does not mean the event handler will run twice. If it runs in capture phase, it won't run in bubbling phase. .capture doesn't prevent child handlers from running; they will still execute after the parent's handler.

2 - I've corrected the @click event handler on the overlay div:

  • !displayOverlay simply returns the opposite boolean value of the current state of displayOverlay; it does not trigger any action.
  • To set displayOverlay to false, you should use
    @click="() => { displayOverlay = false }"
    . Vue allows for a shorter syntax:
    @click="displayOverlay = false"
    (which automatically wraps it with an anonymous function).

3 - <div @click.stop> is shorthand for

<div @click="$event => $event.stopPropagation()">

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

Next.js encountering page not found error due to broken link URL

Currently, I am working on implementing a login system in next.js. In the login page, I have included a Link to the Register page using the Link href attribute. However, every time I click on that link, it displays a message saying "404 page not found." Al ...

What is the best way to navigate users to a different page when they click on a button?

I recently designed a button in Dreamweaver software. Could you please guide me on how to set up the button so that when clicked, it redirects the user to a different page using Dreamweaver? Below is the HTML code for the button: <input type="submit" ...

Failure to display updated property value

After rendering an array of objects, I am attempting to add a new property using a function. However, the new property value is not displaying on the page even though it is present when I log the object in the console. The new property that I want to add ...

Looking to place a global filter outside the primeNG table component?

I am currently utilizing primeNG in my project and I have a need to incorporate a global filter. The challenge I am facing is that I must add this filter in a different component. These two components are deeply nested within other components. My approach ...

A guide to resolving cross-origin resource sharing issues using a reverse proxy

After creating a JavaScript web application for processing documents, I am now looking to integrate with web services like NLTK-server, TIKA-server, and SOLR for further analysis. While I can successfully access the REST endpoints of these services using c ...

Modify the div class depending on the date

I am in the process of creating a simple webpage where I can keep track of all my pending assignments for college. Take a look at the code snippet below: <div class="assignment"> <div class="itemt green">DUE: 28/03/2014</div> </d ...

Enhancing text display and spacing in Safari versions 5 to 6, as well as Chrome

After creating an introductory animation using jquery, I noticed that it displays correctly on my machine in Firefox, Chrome, and Safari. However, when viewing it on the client's devices, the animation is not working properly. The client provided a s ...

Tips on preventing right-click actions in jqGrid

While utilizing onSelectRow in a jqGrid, I have noticed that it functions properly when clicking with the left mouse button. However, when right-clicking, it still triggers the function. My aim is for the right-click to perform its usual action (such as di ...

Instructions for activating and deactivating a numerical input field with a checkbox

Is there a way to create a pair of a checkbox and number field that are linked together? When the checkbox is clicked, it should disable the associated number field. Javascript File: $(document).ready(function(){ $("input[name=check]").click(function(){ ...

Looking to modify the contents of a shopping cart by utilizing javascript/jQuery to add or remove items?

I'm dealing with a challenge on my assignment. I've been tasked with creating a Shopping Cart using Javascript, HTML5, and JQuery. It needs to collect all the items from the shop inside an Array. While I believe I have most of it figured out, I a ...

The SMTP request for a one.com domain email is experiencing issues when sent from the render.com server

I have set up an Express JS server on render.com to handle SMTP calls to an email service hosted on one.com with a custom domain. Utilizing nodemailer to manage the SMTP call: app.post("/send-mail", validate(schema), (req, res) => { console. ...

Troubleshooting media queries on an example webpage

Hey there! So, I'm having a bit of trouble with running media queries on a simple HTML page. It's been a while since I worked on this stuff, and I feel like I must be doing something silly that I can't quite pinpoint. If you want to take a ...

Display issues occur with Bootstrap 4.2.1 flex-box layout columns exceeding the browser edge

Why does COLUMN02 extend beyond the browser's edge when using flex-basis for column widths? What mistake am I making? Unfortunately, it doesn't display correctly in the code snippets here but works in the fiddle. TIA! http://jsfiddle.net/dragont ...

What is the best way to handle multiple promises when loading a state in Angular?

When loading the /home state, I need to retrieve all users from the database in order to customize the home controller and view based on the logged-in user. Currently, in the :resolve section of the state configuration, I am fetching all 'posts' ...

What is the best way to choose the element directly beneath a specific element using jQuery?

I am facing a challenge where I need to manipulate HTML content using only jQuery, without changing the original structure. The requirement is to display and slide down content with a specific class (current) upon clicking on an h1 tag. However, I am strug ...

The table toggle feature seems to be malfunctioning in Safari, whereas it works perfectly in Chrome

My table includes a td element that serves as a toggle switch, transitioning between 3 states flawlessly in Chrome. However, I am facing issues with its functionality in Safari and seek assistance in rectifying the issue to ensure cross-browser compatibili ...

Is there a way to make a sass file universally accessible without having to import it into every file and causing an increase in bundle size?

Question How can I efficiently import variables.scss globally without the need to duplicate them in every file and reference them in my build instead of importing? Setup I am using Vue2 with laravel-mix, where I have imported index.scss in my main.js ...

Retrieve a specified quantity of JSON data from an external API

Dealing with a recently received API from an external source: (please note: the data returned is extensive) I'm aware that I can retrieve this large object by using the following method: $.getJSON('https://www.saferproducts.gov/RestWebServices ...

What is the method for sending raw put data using the request npm package in a Node.js environment

How can I hit an API using the "require" npm package in Node? The API requires raw PUT data instead of PUT fields. Can anyone please guide me on how to achieve this using the request npm package? For example, here is the raw PUT data that needs to be sent ...

Verify if the item already exists in the Vue.js array

Here is the data I have: data: function() { return { conversations: [ ] } } I am retrieving my data from the response object using response.data.conversation Is there a method to verify if this.conve ...