Cancel drop event after catch element with mouse click - javascript

I'm having trouble canceling a drop event. Anyway, I catch the item, and after leaving the area I want to cancel the event and release the item right away. I try this way but it doesn't work:
onDragLeave(event) {
const className = event.target.className;
if (className === 'main-container')
{
const container = document.querySelector('.main-container');
const dragEndEvent = new Event('dragend', { bubbles: true });
container.dispatchEvent(dragEndEvent);
}
}
Function onDragLeave is in html (dragleave) and after I leave container area I want cancel event immediately.Is this done somehow?

Related

how to close created div by clicking outside of it?

I have a div that is created on a button pressed and I'm trying to have it deleted by clicking outside of it but it takes the original button press as clicking outside and immediately closes the div.
closediv();
}
function closediv() {
document.addEventListener("click", (evt) => {
const maindiv = document.getElementById('div3');
let targetElement = evt.target;
do {
if (targetElement == maindiv.childNodes[1]) {
return;
}
targetElement = targetElement.parentNode;
} while (targetElement);
var viewpost = maindiv.childNodes[1];
viewpost.parentNode.removeChild(viewpost);
});
}
In your button click handler, you could use
theButton.addEventListener("click", function(ev) {
ev.stopPropagation();
// rest of the code
});
and the click event would not propagate to the parent containers.
just add a click event on body to close your div and then add prevent default into your div to block closing action when user click on your div
document.body.addEventListener('click', (e) =>{
//close your div here
})
document.addEventListener("click", (evt) => {
evt.preventDefault()
// your code
}

How do I get my modal to close when a user clicks on the container?

I'm currently studying a full stack course and my modal isn't behaving as expected
I'm a bit lost on what to do as I can't find any documentation anywhere and while clicking on the close button or pressing ESC works, clicking outside of the box doesn't.
The following code is how it has been suggested I approach the issue but, it doesn't work. I've honestly stared at this for about an hour and just can't connect the dots on what is (not) happening? Please excuse all the commenting and additional code as I'm still learning so, it's how I'm able to follow what's going on:
function showModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.add('is-visible');
}
function hideModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.remove('is-visible');
}
//modal IFFE
document.querySelector('#modal-button').addEventListener('click', () => {
showModal();
});
//-- show modal --
function showModal(title, text) {
var $modalContainer = document.querySelector('#modal-container');
//Selects the element with the associated id
// Clear all content for the selected element
$modalContainer.innerHTML = '';
var modal = document.createElement('div'); //creates a div element withing selected element
modal.classList.add('modal'); //assigns new class to the div element
// Add the new modal content
var closeButtonElement = document.createElement('button'); //creates the close button
closeButtonElement.classList.add('modal-close'); //assigns a class to the new (close) button
closeButtonElement.innerHTML = "×"; //inserts text within the new(close) button
closeButtonElement.addEventListener('click', hideModal);
var titleElement = document.createElement('h1');
titleElement.innerText = title;
var contentElement = document.createElement('p');
contentElement.innerText = text;
modal.appendChild(closeButtonElement);
modal.appendChild(titleElement);
modal.appendChild(contentElement);
$modalContainer.appendChild(modal);
$modalContainer.classList.add('is-visible');
}
document.querySelector('#modal-button').addEventListener('click', () => {
showModal('PokéMon', 'Here is all of the info about your PokéMon');
});
window.addEventListener('keydown', (e) => {
var $modalContainer = document.querySelector('#modal-container');
if (e.key === 'Escape' && $modalContainer.classList.contains('is-
visible')) {
hideModal();
}
});
$modalContainer.addEventListener('click', (e) => {
var target = e.target;
if (target === $modalContainer) {
hideModal();
}
});
Expected result: User clicks outside of the modal (on the container) and the modal closed.
Current result: No change in state, modal remains active and visible. Only by clicking on the close button (x) or by pressing ESC is the desired result achievable.
By Looking at this code I am not sure what is actually supposed to make the modal visible or hide it. Without access to your css (if you have any). I am assuming that all you are doing is adding and removing the class .is-visible from the #modal-container element.
I would suggest that you apply this class to the modal itself, and then you could toggle this class on and off,
Modify your code to do this by doing something like this (added on top of your code):
function showModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.add('is-visible');
document.querySelector('.modal').classList.remove('hide-el')
}
function hideModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.remove('is-visible');
document.querySelector('.modal').classList.add('hide-el')
}
Where hide-el in your css is:
.hide-el {
display: none;
}
You could also modify your code to appply the is-visible class to your modal element. You should always try to attach the class/id to the element you want to manipulate if you have that option.
Or if you do not have access to a css file:
document.querySelector('.modal').style.display = "none"
and
document.querySelector('.modal').style.display = "block"
Also, your code seems very verbose, was this boilerplate part of the assignment?
heres a working example: https://codepen.io/mujakovic/pen/zVJRKG
The code was in the incorrect place in the end and should have looked something like this:
modal.appendChild(closeButtonElement);
modal.appendChild(titleElement);
modal.appendChild(contentImage);
modal.appendChild(contentHeight);
modal.appendChild(contentElement);
$modalContainer.appendChild(modal);
$modalContainer.classList.add('is-visible');
$modalContainer.addEventListener('click', (e) => { //listening for an event (click) anywhere on the modalContainer
var target = e.target;
console.log(e.target)
if (target === $modalContainer) {
hideModal();
}
});
};
window.addEventListener('keydown', (e) => { //listening for an event (ESC) of the browser window
var $modalContainer = document.querySelector('#modal-container');
if (e.key === 'Escape' && $modalContainer.classList.contains('is-visible')) {
hideModal();
}
});
This is because the action was originally being called on page load and targeted within the window instead of being called within the container and being loaded when the modal loads.
Thank for your help

How to manipulate event bubbling when registering click event upon a layer in mapbox gl js

How can I stop event propagation on layer click events?
mapBox.on('click', layerId, function (e) {
console.log(e);
// e.stopPropagation(); which is not working
// e.originalEvent.stopPropagation(); which is not working
var popupHtml = getPopupHtmlWrapper(e.features[0]);
new mapboxgl.Popup({closeButton:false})
.setLngLat(e.lngLat)
.setHTML(popupHtml)
.addTo(mapBox);
});
Mapbox provides access to the original event. Which means whenever we want to limit a click to the topmost layer clicked only, all we need to do is call e.originalEvent.preventDefault() on the first layer and check for e.originalEvent.defaultPrevented in the layers beneath:
this.map
.on('click', 'layer_1', function(e) { // topmost layer
e.originalEvent.preventDefault();
// layer_1 functionality
})
.on('click', 'layer_2', function(e) { // second topmost layer
if(!e.originalEvent.defaultPrevented) {
// click was performed outside of layer_1
e.originalEvent.preventDefault();
// layer_2 exclusive functionality
}
})
.on('click', 'layer_3', function(e) {
if(!e.originalEvent.defaultPrevented) {
// click was performed outside of layer_1 and layer_2
e.originalEvent.preventDefault();
// layer_3 exclusive functionality here...
}
...
})
Maybe we don't need a global variable, I got the same problems as you, and I fixed it with the solution:
mapbox.on('click', 'layer1', function(e){
e.originalEvent.cancelBubble = true;
/*
//or you can add an attr
e['bubble'] = 'no';
*/
console.log('layer1');
}
mapbox.on('click', 'layer2', function(e){
if(e.originalEvent.cancelBubble){
return;
}
/*
if(e['bubble] && e['bubble'] == 'no'){
return;
}
*/
console.log('layer2');
}
Per the suggestion by #Stophface, I used
e => {
const features = map.queryRenderedFeatures(e.point)
if (features[0].layer.id === myLayerName ) {
doMyClickAction(e)
}
}
so as to only do something with the event when the layer I care about in this instance is the first one that is clicked.
One approach is to save the event coordinates of the click on the layer and then compare these coordinates with the underlying layer and its event coordinates.
let clickCoords = {};
this.map.on('click', 'points', event => {
clickCoords = event.point;
console.log('Layer click')
});
Now, detect a click on the map, not on the points layer
this.map.on('click', () => {
// check if coords are different, if they are different, execute whatever you need
if (clickCoords.x !== event.point.x && clickCoords.y !== event.point.y) {
console.log('Basemap click');
clickCoords = {};
}
});
Or, even better, use queryRenderedFeatures().
this.map.on('click', event => {
if (this.map.queryRenderedFeatures(event.point).filter(feature => feature.source === YOURLAYERNAME).length === 0) {
console.log('Basemap click');
}
});
Here is a Mapbox example.
Was looking to find the same solution, but sharing event between the map and layer, so if layer, for example, was not clicked, I would like map click listener to be invoked, and opposite, if layer was clicked, I would like map click listener to be skipped
So I've ended up with the folowing:
// Event handler for layer
function(e) {
e.preventDefault()
// handle layer event
}
// Event handler for map
function(e) {
if(e.defaultPrevented) return
// handle map event
}
So, prevent default is working but you should check for defaultPrevented property in event and handle it.
I am not aware of any simple way of handling this. I am assuming you are trying to prevent the click event from propagating to an other layer. What you can do is using a global variable storing that a click just happened at those coordinates. Then in your other click handler you check this case.
var recentClicks = {layer1 : null}
mapBox.on('click', "layer1", function (e) {
console.log(e);
recentClicks["layer1"] = e.lngLat
// Proceed to creating pop-up
});
mapBox.on('click', "layer2", function (e) {
console.log(e);
if(recentClicks["layer1"] && recentClicks["layer1"][0] == e.lngLat[0] && recentClicks["layer1"][1] == e.lngLat[1]){
recentClicks["layer1"] = null
return
} else {
// Proceed to treating layer 2 click event
}
});
With a bit of work, you can apply this to an infinite number of layers.
Some of the above suggestions worked after I adjusted my layer ordering by setting the beforeLayer parameter when adding a layer:
https://docs.mapbox.com/mapbox-gl-js/example/geojson-layer-in-stack/
If none of the above suggestions work for you, try playing with the layer order and going through them again.

Correct way to prevent triggering `click` if inner element is not hovered when mouse is released

I need to prevent hiding of a modal dialog when user clicks on the dialog, then moves the mouse outside of the dialog, and releases it. The dialog is placed inside outer div on which the click event is registered. Here is the example of the modal dialog and its setup.
So I've done the following:
var pointerDownElement = null;
$('.d1').on('mousedown', function(event) {
// this is how I do it to prevent triggering of click event
pointerDownElement = event.target;
// this is how a browser does it
pointerDownElement = event.currentTarget;
});
$('.d1').on('mouseup', function(event) {
var element = event.target;
if (element === pointerDownElement) {
console.log('triggering click');
}
});
Is this approach correct?
You're definitely on the right track. Slightly modified code:
var pointerDownElement = null;
$('.d1').on('mousedown', function(event) {
event.preventDefault();
pointerDownElement = event.currentTarget;
return false;
});
$('.d1').on('mouseup', function(event) {
if (event.target=== pointerDownElement) {
console.log('triggering click');
}
});
No need to assign a value to a variable if you're only going to use it once. Also, event.preventDefault(); and return false; will guarantee the default behavior of the event doesn't take place (not that there typically is one for mousedown, but I'm assuming you have a reason for including this code).

Continuous mouse click event

Is there any event generated by continuous mouse click i.e., not releasing the mouse button 1? If no, please let me know.
The mousedown event is triggered when the mouse button is pressed down. If you are looking for an event that fires repeatedly, while the button is held down, you are out of luck, but you can use the mousedown event to repeatedly perform an action, and stop when the mouseup event is triggered.
For example, you could use the setInterval function to repeatedly call a function while the mouse button is down, and then use clearInterval to stop when the mouse button is released. Here is an example (using jQuery):
var interval;
$("#elementToClick").mousedown(function() {
interval = setInterval(performWhileMouseDown, 100);
}).mouseup(function() {
clearInterval(interval);
});
function performWhileMouseDown() {
$("#output").append("<p>Mouse down</p>");
}
You can see this running in this example fiddle.
There is a JQuery plugin: LongClick
Longclick is press & hold mouse button "long click" special event for jQuery 1.4.x.
The event is triggered when the mouse button stays pressed for a (configurable) number of seconds, while the pointer is stationery.
Yes, you can do this using onmousemove= movefunction(event) :
What I did to solve this is the following:
First, create a onmousedown() event that sets a global variable to 1 when triggered.
Second, create a onmouseup() event that sets that global variable to 0 when triggered.
Then, use the onmousemove() event to trigger in the div where I want the mouse down behavior to occur but only if the global variable we set earlier is set to 1.
example on how to use onmousemove(): http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onmousemove
Done.
There is not such event.
What you might implement to achieve this is a function that evaluates the time elapsed between the (first) mouse click ond the following mouse release.
Given a predefined range you can estabilish how long should the button be clicked before being considered valid in your logic.
According to the spec,
A click is defined as a mousedown and
mouseup over the same screen location.
The sequence of these events is:
mousedown, mouseup, click
So no, there isn't a "continuous click", because a click is a descrete event resulting from a sequence of actions.
What you probably want to do, is receive mousedown, set a timer, and if neither mouseup or mousemove occur within some time, invoke some behaviour.
There's a function I've been using to determine if an object is being dragged (if for some reason you cannot use the regular on drag event). Can't be certain that $(':focus')[0] === undefined will work for every situation, but it can be customized.
// this function will set up a mouse drag event and also check if something is being dragged
function customOnDrag(selector) {
var dragInProgress = false;
let mouseDrag = false;
let mouseDown = false;
$(selector).on('mousedown', function(event) {
mouseDrag = false;
mouseDown = true;
interval = setInterval(checkIfDraggingAnObject, 20, event); // set to check every 20 ms
}
).on('mousemove', function(event) {
if ( mouseDown ){
mouseDrag = true;
}
}
).on('mouseup', function(event) {
checkIfDraggingAnObject(event);
clearInterval(interval);
mouseDrag = false;
mouseDown = false;
}
);
// function to check if an object is being dregged:
function checkIfDraggingAnObject(event){
if ( event.type === 'mousedown' ){
if ( $(':focus')[0] === undefined || mouseDrag === false ){
// not dragging an object
dragInProgress = false;
}else{
// dragging an object
dragInProgress = true;
console.log('dragging: ');
console.log($(':focus')); // the object being dragged
};
}else if ( event.type === 'mouseup' ) {
if ( dragInProgress ){
// dropped the object
console.log('dropped: ');
console.log($(':focus')); // the dropped object
dragInProgress = false;
}else if ( mouseDrag ) {
// dragged the mouse, but no object
console.log('did not drag an object');
}else{
// did not drag the mouse
console.log('did not drag the mouse');
}
}
}
}
import java.awt.Robot;
import java.awt.event.*;
public class App {
private static final int key = InputEvent.BUTTON1_DOWN_MASK;
public static void main(String[] args) {
System.out.println("Hello, World!");
Robot robot;
while (1==1) {
try {
robot = new Robot();
robot.mousePress(key);
robot.mouseRelease(key);
// robot.mouseMove(x, y);// x,y are cordinates
// Simulate a mouse click
robot.mousePress(key);
robot.mouseRelease(key);
Thread.sleep(3000);
// Simulate a key board press
// robot.keyPress(KeyEvent.VK_A);
// robot.keyRelease(KeyEvent.VK_A);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

Categories

Resources