How to create MouseEvent in Angular including location properties - javascript

I need to catch click event on button and changing event type only and dispatching it again
something similar below which is in jquery but I want to do it in angular
button.on("click", function(event) {
var newEvent = $.extend({}, event, { type: "dxcontextmenu" });
event.stopPropagation();
$(this).trigger(newEvent);
});
I am able to do dispatchEvent but Event or MouseEvent constructor doesn't have params for screenX or clientX or ...
I tried to use spread operator or Object.Assign but only isTrusted and type properties will be copied.
my code is
onClick(event:any) {
event.stopPropagation();
console.log(event);
const newEvent = Object.assign({}, event, { type: 'dxcontextmenu' });
console.log(newEvent);
event.target.dispatchEvent(newEvent);
// event.target.dispatchEvent(new Event('dxcontextmenu', { bubbles: true }));
}
this is the stackblitz link to it

I found the solution in case other having same problem
openContextMenu(event: MouseEvent)
{
if (event.target)
{
const newEvent = new MouseEvent('dxcontextmenu', { bubbles: true });
newEvent.initMouseEvent(
'dxcontextmenu',
true,
false,
event.view,
event.detail,
event.screenX,
event.screenY,
event.clientX,
event.clientY,
event.ctrlKey,
event.altKey,
event.shiftKey,
event.metaKey,
event.button,
event.relatedTarget
);
event.stopPropagation();
event.target.dispatchEvent(newEvent);
}
}

Related

Ghost image on drag and drop showing siblings

When I drag a div, the sibling at the bottom is showing inside the ghost image.
Illustration :
How to remove the next sibling, here the span "Hello" this one ?
I use Solidjs, and native js drag and drop.
Each component is draggable and droppable.
But a component cannot be drag inside itself or its children.
I listed the different properties and events I use for each component :
const onDrop: main.Attributes['onDrop'] = (event) => {
event.stopPropagation();
removeClass(parent, STRINGS.DROP_CLASS);
if (isDragging()) {
setView({ parent });
} else {
createView({ parent });
}
};
const onDragOver: main.Attributes['onDragOver'] = (event) => {
event.preventDefault();
event.stopPropagation();
// event.currentTarget.style.cursor = 'dragging';
};
const onDragEnter: main.Attributes['onDragEnter'] = (event) => {
event.preventDefault();
event.stopPropagation();
// event.currentTarget.style.cursor = 'dragging';
addClass(parent, STRINGS.DROP_CLASS);
};
const onDragLeave: main.Attributes['onDragLeave'] = (event) => {
event.preventDefault();
event.stopPropagation();
removeClass(parent, STRINGS.DROP_CLASS);
};
const draggable = true;
const setClass = partialCall(setAttribute, id, 'class');
const _backClass =
'!opacity-50 !scale-90 !origin-left !transition !duration-300 !ease-out';
const over = STRINGS.SHOW_BORDER;
// #region Events
const onDragStart: main.Attributes['onDragStart'] = (event) => {
setClass(`${classe} ${STRINGS.DRAG_CLASS}`);
event.stopPropagation();
(event.dataTransfer as DataTransfer).effectAllowed = 'uninitialized';
// event.currentTarget.style.cursor = 'dragging';
if (dragOnly) {
prepareForCreation({ classe, component, ..._props });
} else {
startDrag({ id });
}
setTimeout(() => {
if (dragOnly) {
setClass(`${cl} ${_backClass}`);
} else {
setClass(`${classe} ${_backClass}`);
}
}, 5);
};
const onMouseEnter: main.Attributes['onMouseEnter'] = (event) => {
event.stopPropagation();
!dragOnly && recursiveHoverClass(id);
};
const onMouseOver: main.Attributes['onMouseOver'] = (event) => {
event.stopPropagation();
!dragOnly && recursiveHoverClass(id);
};
const onMouseLeave: main.Attributes['onMouseLeave'] = () => {
removeClass(id, over);
};
const onDragEnd: main.Attributes['onDragEnd'] = () => {
setClass(dragOnly ? cl : classe);
stopDrag();
};
In its current condition your code is hard to reproduce because components are missing, you've posted event handlers only.
If it works for you, you can use solid-dnd, a lightweight and extensible drag and drop library for Solid JS: https://github.com/thisbeyond/solid-dnd

TypeError: binding.value is not a function Vue js v-click-outside

i am using v-click-outside and want to pass value to the function but i am having error
This is how i am passing a value
Here is my code from Main.js file
vue_app.directive('click-outside', {
beforeMount(el, binding, vnode) {
el.clickOutsideEvent = evt => {
evt.stopPropagation()
if (!(el === evt.target || el.contains(evt.target))) {
binding.value(evt, el)
}
}
// Wait 1 frame otherwise a potential click that mounted the element will immediately trigger a click-outside event:
window.requestAnimationFrame(() => {
document.addEventListener('click', el.clickOutsideEvent)
})
},
unmounted(el) {
document.removeEventListener('click', el.clickOutsideEvent)
},
});
You have to pass a function to the directive, but right now you call it right away and pass the returned value. So instead of
v-click-outside="hideAllShowDetailDropdown(show.show_ID)"
Try this:
v-click-outside="() => hideAllShowDetailDropdown(show.show_ID)"

How to remove Event Listener using MutationObserver?

I have a problem, I can't remove the event listener in the condition inside the callback function.
I have the impression that the syntax is correct. But the event is still active.
Does anyone know how to remove the event touchstart?
mutation.target.removeEventListener("touchstart",(e) => { handleClickButton(e) }, true);
const headerSearchBox = document.querySelector(".search-box");
function handleClickButton(event) {
event.preventDefault();
alert("You Clicked on the button")
}
const mutationCallback = function (mutationList) {
mutationList.forEach((mutation) => {
let isSearchOpen = mutation.target.classList.contains("search-container");
// If Search Bar is Open : Do This...
if (mutation.type === "attributes" && isSearchOpen && mutation.oldValue.includes("open")) {
console.log("Search Bar is Open");
mutation.target.addEventListener("touchstart",(e) => { handleClickButton(e) }, true);
} else {
console.log("Search Bar is Close");
mutation.target.removeEventListener("touchstart",(e) => { handleClickButton(e) }, true);
}
});
};
const observer = new MutationObserver(mutationCallback);
observer.observe(headerSearchBox, {
attributes: true,
attributeOldValue: true,
attributeFilter: ["class"],
});
Thanks for your support

Pass parameter from a function to this.setState callback function

I'm a facing a bit of a problem here. I'm trying to pass a parameter from a function to this.setState callback, but I can't figure out how is this possible.
My code looks like this:
selectHandler(event){
this.setState({
selectedImage: event.target
}, (event) => {
this.markSelectedHandler(event)
})
}
markSelectedHandler(e){
e.target.classList.add('active')
if(e.target !== this.state.selectedImage && this.state.selectedImage){
this.state.selectedImage.classList.remove('active')
e.target.classList.add('active')
}
}
e.target returns null, any idea why this happens ?
The event will not work async. You will need to extract the values or use e.persist() reactjs.org/docs/events.html#event-pooling
You could however say:
selectHandler(event){
const { target } = event;
this.setState({
selectedImage: target
}, () => {
this.markSelectedHandler(target)
})
}
markSelectedHandler(target){
target.classList.add('active')
if(target!== this.state.selectedImage && this.state.selectedImage){
this.state.selectedImage.classList.remove('active')
target.classList.add('active')
}
}
But I will recommend against it..
To be honest, you should not add your class with DOM manipulating but instead add it in your render <img className={this.state.selectedImage === myImage ? 'active' : undefined} />
You are shadowing your event in this code:
selectHandler(event){
this.setState({
selectedImage: event.target
}, (event) => {
this.markSelectedHandler(event)
})
}
You need not to shadow, by not passing a parameter with the same name (event to the setState callback):
selectHandler(event){
this.setState({
selectedImage: event.target
}, () => {
this.markSelectedHandler(event)
})
}
Try not sending event as an argument to the callback
eg you have written
selectHandler(event){
this.setState({
selectedImage: event.target
}, (event) => {
this.markSelectedHandler(event)
})
}
Write like this instead
selectHandler(event){
this.setState({
selectedImage: event.target
}, () => {
this.markSelectedHandler(event)
})
}

Is it possible to use Mutation Observer with a Three js element - A-Frame?

export class ColliderComponent {
constructor() {
this.observer = this.mutationObserver();
this.aframe();
}
//Registers the AFRAME component.
aframe(){
const __this = this;
AFRAME.registerComponent('collider', {
schema: {
},
init: function () {
console.log("The element to be observed is:",this.el);
__this.observer.observe(this.el, {characterData:true, subtree:true, attributes: true, attributeFilter: ['position'], childList : true});
},
tick : function(){
console.log(this.el.getObject3D('mesh').position);
}
});
}
private tick(){
}
private mutationObserver() : MutationObserver{
return new MutationObserver(mutations => {
mutations.forEach(mutation => {
console.log("Changed position");
});
});
}
}
I'm working on creating a simple collider. I'm going to track the elements that have the "collider" component and check if they're intersecting using intersectsBox. Unfortunately, I can't seem to make the MutationObserver to work. I'd rather use this approach instead of the tick, because it will start executing it per frame, instead when the elements move.
Any suggestions?
You can use
el.addEventListener('componentchanged', function (evt) {
if (evt.detail.name === 'position') {
}
});
But polling/ticking via tick is synchronous and probably still not a bad way to go.

Categories