Vue.js event target is null? - javascript

I got a component with two styled buttons and one same event
"mouseEnter".
<template>
<div>
<a
class="button red"
href="/about"
#mouseover="mouseEnter">
<svg viewBox="0 0 180 60">
<path d="..."/>
</svg>
<span class="buttonSpan">About</span>
</a>
<a
class="button green"
href="/contact"
#mouseover="mouseEnter">
<svg viewBox="0 0 180 60">
<path d="..."/>
</svg>
<span class="buttonSpan">Contact</span>
</a>
</div
</template>
When the event triggers I want to do something with the path and the span of the button that is hovered.
I'm trying to reference them with event.target but for the span I get null, and for the path everything is working good.
methods: {
buttonEnter(event) {
const buttonPath = event.target.querySelector('path')
const buttonSpan = event.target.querySelector('span')
...
}
How should i reference the span ? Is there any other way I can do it ?

the event target will bubble up starting from the children of the node that you attached your listener to. Use event.currentTarget

Related

how to open 1 modal window with 3 different buttons?

I face the problem of opening the same modal window with different buttons. Unfortunately, my knowledge is not enough to solve the problem correctly. I made several scripts for each button, it works like this, but it's not a solution, there should be one code, but how exactly to write it?
An example of the code for 1 button below, I will be grateful for help in supplementing the opening code for the other 2 buttons.
(() => {
const refs = {
openBuyModalBtn: document.querySelector("[data-buy-modal-open]"), <sup>open button</sup>
closeBuyModalBtn: document.querySelector("[data-buy-modal-close]"), <sup>close button</sup>
buyModal: document.querySelector("[data-buy-modal]"),
body: document.querySelector("body"),
};
refs.openBuyModalBtn.addEventListener("click", toggleModal);
refs.closeBuyModalBtn.addEventListener("click", toggleModal);
function toggleModal() {
refs.buyModal.classList.toggle("is-hidden"); (.is-hidden {opacity: 0; pointer-events: none; transform: scaleX(0);} )
refs.body.classList.toggle("no-scroll");
}
})();
<button class="buy-now__button" data-buy-modal-2-open type="button">Buy now
<svg width="32" height="32" class="buy-now__icon">
<use href="./images/svg/icons.svg#icon-ep-arrow"></use>
</svg>
</button>
<button class="header-nav__button" data-buy-modal-open type="button">Buy now
<svg width="32" height="32" class="header-nav__icon">
<use href="./images/svg/icons.svg#icon-ep-arrow"></use>
</svg>
</button>
<div class="buy-modal__container is-hidden" data-buy-modal>
<div class="buy-modal">
<button class="buy-modal__button buy-modal__button--close" type="button" data-buy-modal-close>
<svg width="20" height="20">
<use href="./images/svg/icons.svg#icon-close"></use>
</svg>
</button>
<h2 class="buy-modal__title">Buy now</h2>
<ul class="buy-modal__picture-list"></ul>
</div>
</div>

Vue3 Move/drag image vertically

I have an image inside a wrapper div. I want to move the image vertically inside the div because the image does not fit.
I found a few libs that do this in react but not many resources for Vue
I want to achieve a functionality like in Google Maps, where you can drag the map around. The map view always stays inside the wrapping container and the move extends only until the image top/bottom is reached
<script setup>
...
onMounted(() => {
let bgDiv = document.getElementById("test");
bgDiv.addEventListener('mousemove', e => {
let y = e.offsetY;
bgDiv.style.cssText = `transform: translate3d(0, ${y}px, 0)`;
});
})
</script>
<div class="test" id="test">
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1920 1080"
preserveAspectRatio="xMinYMin meet"
class="svg-content">
<!-- overhead appears when viewbox > image, otherwise should be fine, so just make them match/fit -->
<image
width="1920"
height="1080"
xlink:href="#/assets/background.gif"></image>
<a class="cursor-pointer" data-bs-toggle="modal" data-bs-target="#">
<rect
x="618"
y="140"
fill="#fff"
opacity="0.5"
width="155"
height="940"/>
</a>
</svg>
</div>

How to get element whose onClick has been fired on click of any child element

My HTML code is similar to this:
<a onclick="customerDelete056b0d37(event)" id="ixnat-d26294a3" data-id="dsddsss3226294a3">
<i data-js="icons" id="it2ul" class="icons">
<polyline points="21 8 21 21 3 21 3 8"></polyline>
<rect x="1" y="3" width="22" height="5"></rect>
<line x1="10" y1="12" x2="14" y2="12"></line>
</i>
</a>
Now I want to get the <a> element if any of the child elements get clicked.
As e.target did return the element that has been click.
Suppose <rect x="1" y="3" width="22" height="5"></rect> got clicked.
then e.target will return <rect x="1" y="3" width="22" height="5"></rect>
But I want the element that has onClick associated like in this case. It will be
<a onclick="customerDelete056b0d37(event)" id="ixnat-d26294a3" data-id="dsddsss3226294a3">
So I can get the data-id attribute of this element. (It can be some other attribute too, just wrote data-id as an example).
Also as I can not use the closest as it will not have a fixed position, nor this will always be a tag. It could be another tag like button.
How to get the element that has event handler on click of child element?
Note: None of the attribute or attribute values will be fixed. All will be dynamic.
You can use currentTarget for that. It refers to the element on which the event listener was set
The currentTarget read-only property of the Event interface identifies the current target for the event, as the event traverses the DOM. It always refers to the element to which the event handler has been attached, as opposed to Event.target, which identifies the element on which the event occurred and which may be its descendant.
Documentation
Usage
<a onclick="customerDelete056b0d37(event)" id="ixnat-d26294a3" data-id="dsddsss3226294a3">
<i data-js="icons" id="it2ul" class="icons">
<polyline points="21 8 21 21 3 21 3 8"></polyline>
<rect x="1" y="3" width="22" height="5"></rect>
<line x1="10" y1="12" x2="14" y2="12"></line>
</i>
</a>
And in the javascript
function customerDelete056b0d37(event) {
/* This will be the a element */
var a = event.currentTarget;
}
You can use the closest method with DOMString like #id or .class etc. Something like this:
const customerDelete056b0d37 = (event) => {
console.log(
event.target.closest("#ixnat-d26294a3")
);
};
<a
onclick="customerDelete056b0d37(event)"
id="ixnat-d26294a3"
data-id="dsddsss3226294a3"
>
<i data-js="icons" id="it2ul" class="icons">
<polyline points="21 8 21 21 3 21 3 8"></polyline>
<rect x="1" y="3" width="22" height="5"></rect>
<line x1="10" y1="12" x2="14" y2="12"></line>
</i>
</a>
Some other approaches you can take:
1)
event.target.closest('[data-id="dsddsss3226294a3"]')
event.target.closest("[data-id]")
NOTE: All the mention ways are not the same, but will work same for the above example.
You can send the id of <a> tag as argument to function customerDelete056b0d37("ixnat-d26294a3") and use document.getElementById method to get the element in the body of customerDelete056b0d37 function.

onClick function doesnt take the value when i click on elements inside the button

function handleClick(e) {
console.log(e.target.value)
}
<Button value={id} onClick={handleClick} id="like-button" variant="light">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" className="bi bi-heart-fill" viewBox="0 0 16 16">
<path fillRule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" />
</svg>
<p>Like</p>
</Button>
when i click on the button i get the value id, but if i click on elements inside the button i get the value of the element that got clicked. any idea how can i get the value -id- no matter where i clicked on?
use event.currentTarget instead of event.target

How do I access an event's actual target when a child element triggers the event?

I'm listening on this button for a click event, which would run toggleSubMenu() method of a Vue instance. I want it so that when the button is clicked I can get the event.target's parentNode which would be the div with a class of sub-menu-sibling, and then it's nextElementSibling which would be the div with a class of sub-menu. This is my HTML structure.
<div class="sub-menu-sibling">
<button #click.stop="toggleSubMenu($event)" class="btn" type="button" name="button">
<svg class="bi bi-chevron-right" width="14px" height="14px" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L10.293 8 4.646 2.354a.5.5 0 010-.708z" clip-rule="evenodd" />
</svg>
Show Menu
</button>
</div>
<div class="sub-menu">
<!-- menu items -->
</div>
This is my Vue app
const Menu = Vue.createApp({
methods: {
toggleSubMenu: function(event) {
const subMenus = document.querySelectorAll("#categoriesMenu .sub-menu");
let targetSubMenu = event.target.parentElement.nextElementSibling;
targetSubMenu.classList.toggle('show');
subMenus.forEach((sub) => {
sub.classList.contains('show') && sub != currentSubMenu ? sub.classList.remove('show') : ''
});
}
}
})
The problem is that when a user clicks directly on the svg icon inside the button, it becomes the event.target, which breaks my whole expectation. How do I get it to listen primarily on the button's surface alone?
You can apply stop propagation on the action button
const stopPropagation = event => {
event.cancelBubble = true
event.preventDefault()
if (event.stopPropagation) event.stopPropagation()
}
and
const toggleSubMenu = () => {
stopPropagation()
...
}
===UPDATE
I didn't know event.currentTarget existed.

Categories

Resources