mousedown Events in RaphaelJS not working - javascript

I have run into the problem that RaphaelJS doesn't react to mousedown/mousemove/mouseup Events but works fine with .click().
I created this http://jsfiddle.net/JMu7Z/2/ to show what i mean.
JS code:
var containerDivs = document.getElementsByClassName('container');
var overlayDiv = null;
for(var k=0;k<containerDivs[0].childNodes.length;k++)
{
if (containerDivs[0].childNodes[k].className.indexOf("holder") !== -1)
overlayDiv = containerDivs[0].childNodes[k];
}
var canvas = Raphael(overlayDiv,208,270);
var bgr = canvas.rect(10,10, canvas.width-10, canvas.height-10).attr({fill: "0xFF0000", stroke: "none", opacity:"0.2"});
bgr.mousedown( function(e) { alert ("down"); }); //doesn't work
bgr.click( function(e) { alert ("click"); }); // works
Html:
<div class="container" style="position: relative; left: 0; top: 0;"><img class="corePic nonselectable" style="position:relative; top: 0; left: 0;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Tesla3.jpg/220px-Tesla3.jpg" alt="2_3"><div class="holder nonselectable" style="position:absolute; top:0px; left:0px;" onselectstart="return false;"></div></div>
Any help is highly appreciated.

Look at the DEMO I provided based on you example.
//bgr.click(function(){this.attr({stroke:'orange',"stroke-width":5,opacity:0.5});
bgr.mousedown(function()
{
this.attr({stroke:'red',"stroke-width":5,opacity:0.5});
});
bgr.mouseup(function()
{
this.attr({stroke:'blue',"stroke-width":5,opacity:0.5});
});
//bgr.mousemove(function(){this.attr({stroke:'green',"stroke-width":5,opacity:0.5});
Take note that there are some listeners that cannot be used simultaneously.
For example:
click and mousedown events should not be used together on the same object. Why? Because the mosedown event triggers as soon as you push mouse button down; whereas click is different. If you look at the DEMO, comment everything and uncomment click. When you press and hold the mouse button nothing happens until you release the button. That is why when you have both events on the same object, mousedown triggers first and takes over the click.
mouseup and mousemove also act similar to the previous point. mousemove triggers right away and takes over 'mouseup' event. That is why you can only see mousemove event on the object that has both events implemented.
Plus, mousemove is really annoying. When you have it, it will not even let you click, mousedown, or mouseup events from happening. In all three cases it triggers and stays on the whole time your mouse is over the element.
Hope this helped a little.

Related

Drag event not firing with angular 2

I have a canvas and I want users to be able to drag graphic elements around it. Thus, I don't want the canvas itself to drag, but I want to handle dragstart, drag, and drop events when the mouse does those things.
I'm using Angular 2, so I have:
<!-- editor.component.html -->
<div #rendererContainer
draggable="true"
(dragstart)="onDragStart($event)"
(drag)="onDrag($event)"
(dragover)="onDrag($event)"
(drop)="onDragEnd($event)"
(dragend)="onDragEnd($event)">
</div>
Then in editor.component.ts:
onDragStart(event) {
console.log(`starting`);
event.preventDefault();
}
onDrag(event) {
console.log('dragging');
event.preventDefault();
}
onDragEnd(event) {
console.log('drag end');
event.preventDefault();
}
When I try dragging something, I get starting printed in the console, but that's it. How do I get the other drag events to fire? Do I have to roll my own dragging from mousedown/move/up events?
Stand-alone example on stackblitz. I want "dragging" the div around to fire dragstart/drag/drop events, but it only fires the starting one.
You do not have to use event.preventDefault(). This is only necessary if you want to use pure JS.
Try this Stackblitz: https://stackblitz.com/edit/angular-x7umar
Also refer to the MDN implementation guide to choose the right events for your purposes: https://developer.mozilla.org/en-US/docs/Web/Events/drag
Further steps
If you want to modify the dragged element, simply implement some CSS adjustments inside your dragstart and dragend handler of the event.target:
onDragStart(event: DragEvent) {
console.log(`starting`, event);
// Hide dragged element
event.target.style.opacity = 0;
}
onDragEnd(event: DragEvent) {
console.log('drag end', event);
// Show dragged element again
event.target.style.opacity = 1;
}
With event.target you have the complete manipulable DOM element of the dragged element.
try with
(dragover)="onDragOver($event)"
(dragleave)="onDragLeave($event)"
Component
onDragOver(event) {
// do something
event.preventDefault();
}
onDragLeave(event) {
// do something
event.preventDefault();
}

hide popup by clicking outside of it

I read this article saying a popular way to close popups by clicking anywhere outside of the popup is a bad practice
https://css-tricks.com/dangers-stopping-event-propagation/
He gives an alternative solution in the article
$(document).on('click', function(event) {
if (!$(event.target).closest('#menucontainer').length) {
// Hide the menus.
}
});
Explanation of the above code: "The above handler listens for clicks on the document and checks to see if the event target is #menucontainer or has #menucontainer as a parent. If it doesn't, you know the click originated from outside of #menucontainer, and thus you can hide the menus if they're visible."
I don't use jQuery so am trying to implement something similar in vanilla.js.
One thing I tried is to stop pointer events with CSS, but there might be things inside the inner-popup, like a button, that I do want to be clickable
If it confuses matters - My popup is a black overlay with a lowered opacity with then another div inside to be the actual popup.
I tried this but it didn't work - I'm attaching the listener only after showing the popup:
function showPopup(popup) {
popup.style.display = "flex";
popup.addEventListener("click", function(event) {
if (!event.currentTarget.contains(target)) {
closePopup(event.currentTarget);
}
})
EDIT: this works
function clickOutsidePopup(e, popup) {
console.log(e.target)
if (e.target.querySelector(".inner")) {
closePopup(popup);
}
}
Dont stop the pointer events, write a function that works instead, something like this :
document.addEventListener('click', function(e) {
var el = e.target.closest('#menucontainer');
if (el) {
// click inside the popup
} else {
// click outside the popup
}
});
Remember to remove the event handler when the popup is closed, otherwise you'll have multiple event handlers cancelling each other out.
Note that element.closest() need a polyfill to work in IE.
Approach a simpler way:
Create an overlay which covers the whole body (positition absolute; top: 0; left: 0; width 100%; height: 100%; z-index: 2). Attach an onclick event which triggers the modal.close();
Put your modal over that overlay. When the overlay is clicked, just remove it and close the modal. (position: absolute; z-index: 3);

getting a mouseenter event from a still mouse entering an animated element

I'm writing a image carousel and due to some class adding/removing my css pointer as well as my mouseenter event don't seem to work properly.
$("img", ":not(.active)").on("click", function() {
var $this = $(this);
$("img").removeClass("active");
$this.addClass("active");
goto($this.index());
});
$("img").on("mouseenter", function() {
console.log("silence");
});
function goto(i) {
$(".images").animate({
left: 55-i*310
});
}
http://jsfiddle.net/rnfkqq6s/3/
please take a look at the fiddle and watch the console. when the mouse doesn't move while clicking, the mouseenter sometimes isn't beeing triggered. the same thing with the cursor. what am I doing wrong here?
This issue relates to a known bug:
See similar:
Getting the browser cursor from "wait" to "auto" without the user moving the mouse
The bug report:
https://code.google.com/p/chromium/issues/detail?id=26723#c87

HammerJS triggers click after dragend

I have a perfectly working hammerjs drag listener that captures drags just like I'd expect. But when you let go, right after the dragend is triggered, it then triggers a click event as well. So if you were clicking to drag (move) the target, and the cursor happened to be over a link, when you let go (drop), it triggers a click on the link, which I don't want.
Here's my code:
$('.draggable').hammer({
drag_min_distance: 0,
drag_max_touches: 2,
drag_lock_to_axis: true,
drag_lock_min_distance: 30
}).on('drag', handleMiddleEvent)
.on('dragstart', handleStartEvent)
.on('dragend', handleEndEvent);
If I console.log the event on all three handlers and console.log click events on all links, I get something like this in my console:
dragstart
dragmiddle
dragmiddle
dragmiddle
dragmiddle
dragend
click
I want to avoid the click at the end. I tried adding event.stopPropagation() to all of the handle methods, but to no avail.
Try using Hammer.js tap events instead of the click events on the links.
I had a pretty similar problem, and found some kind of workaround - I know it's dirty but the links are not being clicked by a drag. I want to drag a wrapper-div, which is my wrapper element seen in the js below. It has several links in it, wich are being clicked when the dragging stops above them, and i want to prevent that from happening.
First, i define a div that is on top of everything but set hidden in my html:
<div id="wrapper">
<div id="linklist">
<-- Links etc in here-->
<div id="preventClick" style="visibility: hidden; position: absolute; width: 5000px; height: 6000px; "></div>
</div>
</div>
Then, in the hammer functions, the div is set to visible at a dragstart (in this case, a dragdown) - you just can't see it because it has no background-color or any content.
JS:
var wrapper = document.getElementById("wrapper");
Hammer(wrapper).on("dragdown", function() {
handleDragDown(); //call function that handles movement
var preventClick = document.getElementById("preventClick");
preventClick.style.visibility = 'visible';
});
Hammer(wrapper).on("dragend", function() {
var preventClick = document.getElementById("preventClick");
preventClick.style.visibility = 'hidden';
});
I know this is far from perfect and your post is from several months ago, but it worked for me. Hope i could help :)

OnMouseMove dragging, target wrongly intercepting events

I have target that should move around in it's parent, where that parent is clicked.
Some Fiddle: http://jsfiddle.net/GMerZ/
Some HTML:
<div id="rControl">
<p>R1 / R2</p>
<div class="widget">
<div class="target"></div>
</div>
</div>
Some jQuery via CoffeeScript:
rControl = $('#rControl')
widget = rControl.find '.widget'
target = rControl.find '.target'
clicked = no
widget
.mousedown =>
clicked = yes
.mouseup =>
clicked = no
.mousemove (e) =>
if clicked
target.css
top: "#{e.offsetY}px"
left: "#{e.offsetX}px"
Problem is the target jitters around as you drag. It seems to be that the first event places the widget under the cursor, and the second event occurs on the target and not the widget background, so the offset is now relative to the target, not the parent widget, and the offset values are much smaller. The target now incorrectly moves to the top left of the widget.
Clearly, the target should not be handling these events, and should not be providing click location info based on the target's position.
How can I make this work so that I get the mouse position relative to .widget on every firing of the event, regardless of whether or not the mouse is in the .target?
Also, I'd love to do this without rearranging the HTML forcing the target under the widget, there must be a tricky bit of event delegation magic I'm missing.
Just filter out mousemove calls to only act on the ones fired by widget:
Updated JS (just one small change to the mousemove if):
rControl = $('#rControl')
widget = rControl.find '.widget'
target = rControl.find '.target'
clicked = no
widget
.mousedown =>
clicked = yes
.mouseup =>
clicked = no
.mousemove (e) =>
if clicked and e.target == widget[0]
target.css
top: "#{e.offsetY}px"
left: "#{e.offsetX}px"
See on jsfiddle.

Categories

Resources