Javascript drag and drop - delay for allowdrop - javascript

I'm currently stuck at the following problem:
I need to create a delay when dragover happens en then check if current dragover object is still the same. When it's the same object -> execute code.
This is my code:
var draggedId = null;
var triggered = false;
function allowDrop(ev) {
draggedId = ev.target.id;
setTimeout(function () {
if (draggedId == ev.target.id && ev.target.id != "" && !triggered) {
triggered = true;
draggedId = "";
ev.preventDefault();
}
}, 2000);
}
function drop(ev) {
ev.preventDefault();
}
function dragLeave(ev) {
draggedId == "";
triggered = false;
}
Allowdrop function is the dragover event.
ev.preventDefault() to allow the drop can't happen there because that function is assync.
Any idea's?
Thanks,
Mathias

Can you explain more about what you are trying to achieve and I can answer more fully ?
It's generally the case that you cannot always say for certain whether a drop will work, the best you can do is to setup drop zones on your page and have them cancel the dragover event based on what you can tell about the drop. If you want to make your application work with cross window dragging, then you cannot rely on a global variable to store information about what is being dragged, and you cannot actually see what is inside the drag - you can only know what kind of thing is being dragged. So if the drop might be acceptable you need to cancel the event. See this question
I think that maybe you are confused about how dragevents propagate which is the reason you think you need a timeout ? But blocking the event queue to figure out whether you accept a drop, or trying to cancel the drag event after it has already bubbled to the top and been handled in the default way by the browser (which is to not accept the drop) isn't going to work.

Related

How can I catch the click outside the browser - Javascript

For my project, I need to catch all the click outside the browser in Javascript. Is there a way to do that ? For example by asking the user the right access ?
I need a function like "onclick" that works even outside the browser.
There are various approaches for detecting when the focus moves out of the current page which would be a side effect of clicking outside the window if the window currently has focus.
Explicitly detecting clicks outside the page is not possible. It would be a security problem if a web page could monitor how the user interacts with other applications.
To detect click outside element with JavaScript, we can use the element’s contains method.
For instance, we write
const specifiedElement = document.getElementById("a");
document.addEventListener("click", (event) => {
const isClickInside = specifiedElement.contains(event.target);
if (!isClickInside) {
// ...
}
});
to select the element we want to check with getElemebntById.
Then we add a click listener for the whole page with document.addEventListener.
In the callback, we call specifiedElement.contains with event.target to check if we clicked inside the a element.
If it’s false, then we clicked outside of it.
javascript detect click outside of element
var ignoreClickOnMeElement = document.getElementById('someElementID');
document.addEventListener('click', function(event) {
var isClickInsideElement = ignoreClickOnMeElement.contains(event.target);
if (!isClickInsideElement) {
//Do something click is outside specified element
}
});
click outside javascript
// Vanilla js
var ignoreMe = document.getElementById("ignoreMe");
window.addEventListener('mouseup', function(event){
if (event.target != ignoreMe && event.target.parentNode != ignoreMe){
// Place your output
}
});
https://www.codegrepper.com/code-examples/javascript/javascript+detect+click+outside+of+element

html element got focused by mouse or keyboard

How can I find out a HTML-Element (lets say a select-tag) got focus by mouse-click, keyboard or JavaScript function?
<select onfocus="foo(event)"></select>
<script>
function foo(e) {
if (e.??? == 'mouse') {
//do something
}
else if (e.??? == 'keyboard') {
//do something different
}
}
</script>
I also tried to add an onclick event to the element but the onfocus event fires first.
I don't believe there is any native way to see how the element received its focus (correct my if I'm wrong!).
However, you may be able to do something like store when the mouse is clicked, store when the keyboard is used and then react based on the last active state.
var inputState = null;
document.addEventListener("click", handleClick);
document.addEventListener("keyup", handleKey);
function handleClick () {
inputState = "mouse";
}
function handleKey () {
inputState = "keyboard";
}
function foo() {
if ( inputState === "mouse" ) {
// mouse code
} else if ( inputState === "keyboard" ) {
// keyboard code
} else {
// Function was called directly
}
// Reset input State after processing
inputState = null
}
This will likely need some adjustments but I hope you can use this to find the correct answer.
Edit:
My answer is a vanilla JS solution, if you have access to jQuery you may want to investigate the click and keyup event handlers.
Use document.activeElement, it is supported in all major browsers. It can give you the current active element.
EDIT
Oops I think I misunderstood your question. you want to identify the mouse or keyboard or programmatic
For programmatic
if(e.hasOwnProperty('originalEvent')) {
// Focus event was manually triggered.
}
To differentiate between keyboard and mouse based focus events
You have to hack it by adding an extra keydown event and understand. You can not differentiate it like you want.
If you want to check wheather < select > is clicked by keyboard or mouse,
you can use mousedown() and keypress() event
$('select').mousedown(function(e){
//your code on mouse select
});
and
$('select').keypress(function(e){
//your code on key select
});

How to cancel an HTML5 drag (and drop) operation using Javascript?

I want to cancel an HTML5 drag operation based on some condition. I have tried to search this but found nothing useful. It seems that there is no way to cancel an HTML5 drag and drop using JavaScript. returning false in the dragstart doesn't seem to do anything. Any ideas?
You can cancel it by calling event.preventDefault() in the event handler.
For example this should work:
<p id="p1" draggable="true" ondragstart="dragstart_handler(event);">This element is draggable.</p>
<script>
var enableDragDrop = true;
function dragstart_handler(ev) {
if (!enableDragDrop) {
ev.preventDefault();
}
console.log("dragStart");
}
</script>
I think you need to do something tricky to make it work, for I do not know how to stop a drag from js, but you can fake a drag with mousedown,mousedown,mouseup and a isDragging flag
some code look like:
var isDragging = false
var fakeDraggingElement
var currentDragging
$('#item').mousedown(function(e){
e.preventDefault()
isDragging = true
currentDragging = this
//change your cursor and make it loos like dragging
$('#parent').css({cursor: 'move'})
//fake dragging element
fakeDraggingElement = $(this).clone().css({
opacity:0.5,
position:'absolute',
top:e.pageY+offsetY, //parent offset
left:e.pageX+offsetX,//parent offset
}).appendTo(parent)
}).mousemove(function(e){
if(!isDragging){
return
}
fakeDraggingElement.css({
top:e.pageY+offsetY, //parent offset
left:e.pageX+offsetX,//parent offset
})
}).mousedown(function(e){
if(!isDragging){
return
}
cancleDrag()
//your old drop
ondrop(currentDragging,e.target)
})
function cancleDrag(){
isDragging = false
$(currentDragging).remove()
currentDragging = undefined
}
EDIT:
got it. Its a bit roundabout, but works. Take advantage of the fact that the drag event is a cancellable mouse event, and cancelling it stops all further drag actions. Create a drag event on your condition and call preventDefault(). The following cancels it after 3 seconds:
setTimeout(function(){document.getElementById("drag").ondrag = function(e){
e.preventDefault();
this.ondrag = null;
return false;
};},3000);
Note first that I clear all ondrag events after it is cancelled, which you may need to adjust if you need other ondrag events, and second that this truly cancels all parts of the drag, so you don't get an ondragend event after, as shown in this jsfiddle:
http://jsfiddle.net/MaxPRafferty/aCkbR/
Source: HTML5 Spec: http://www.w3.org/html/wg/drafts/html/master/editing.html#dndevents

Fire an Event Only After Another Event Has Been Fired

I have a GeoExt map panel with a zoom control. I'd really like to disable some of the nodes in a tree panel when the layers on my map are "out of range" aka their setVisibility is set to false. I have my zoomend event working and I also have a checkchange event working, but the checkchange event gets evaluated more than once if the user pushes the zoombar more than one level and the other problem is that even after the zoomend event is over the checkchange still gets fired every time the user merely clicks the node's checkbox on or off. I really need a way to control this checkchange event to only run once and to stop it from firing if the user is not using the zoombar...
map.events.on({ "zoomend": function (e) {
layerTree.on("checkchange", function (node, checked) {
alert(node.text + "Inside event");
if(checked == false)
node.disable();
else if(checked == true)
node.enable();
});
if (this.getZoom() > 7) {
tib_villages.setVisibility(true);
tib_lakes.setVisibility(true);
tib_townships.setVisibility(true);
}
else {
tib_villages.setVisibility(false);
tib_lakes.setVisibility(false);
tib_townships.setVisibility(false);
if (this.getZoom() > 5) {
infrastructure.setVisibility(true);
geography.setVisibility(true);
geography2.setVisibility(true);
tib_countys.setVisibility(true);
}
else{
infrastructure.setVisibility(false);
geography.setVisibility(false);
geography2.setVisibility(false);
tib_countys.setVisibility(false);
}
}//end else
}//end function (e)
}); //end map.events.on
Thank you for all your time and feedback :)
elshae
It turns out that the work has already been done for us :). There is a patch at http://trac.geoext.org/attachment/ticket/235/autoDisableLayerNode.patch which will automatically disable/enable nodes based on their minScale/maxScale properties etc. I applied the patch by putting this file in my GeoExt directory and running the following command in my GeoExt directory:
patch -p0 < autoDisableLayerNode.patch
I hope this helps! It worked wonders for me :)
elshae

Ignoring/canceling browser drag for JavaScript drag & drop

I'm implementing a drag & drop script in (plain) JavaScript. All good, except one thing. For example, in Firefox (probably not only there), if you drag an object the second time, it is getting dragged as a built-in browser feature (for easy drag & drop image saving to desktop, for example, I think). Well this kind of ruins my script.
Thing is, I know this is possible, and I've even done it before, but that was like a long time and I got it working by trial and error, just entered focus() and blur() all over the place 'till it seemed to actually loose focus.
So if someone knows how to clear this out for me, he'd be my personal hero. Blur() on the dragging object? focus() on a different one? etc.
Thanks!
//Ok, the parts of the code regarding this would be:
...
this.handle.onmousedown = function(e)
{
self.startDragging(e);
};
this.handle.onmouseup = function(e)
{
self.stopDragging(e);
};
setInterval(function(){self.animate()}, 25);
...
startDragging: function(e)
{
this.dragging = true;
},
stopDragging: function(e)
{
this.dragging = false;
},
animate: function()
{
if(this.dragging)
...
Unless I misinterpreted your question, try event.preventDefault(); in your mousedown event listener. It would help if you could provide snippets of code to show us how you are implementing drag/drop.
Edit: With your implementation, something like this should work:
this.handle.onmousedown = function(e) {
if(!e) e = window.event;
if(e.preventDefault) e.preventDefault();
else e.returnValue = false;
self.startDragging(e);
};
However, I would recommend using event listeners instead.

Categories