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
Related
I can not seem to get Photoswipe to prevent a drag/swipe from changing slides (so only the arrows go to the previous/next slides)
The issue is that I've got a HTML slide with touch events inside it, but photoswipe's touch events are superseding them and while dragging around in the content of the slide, the entire slide moves too...
I thought this event was supposed to prevent it?
pswp.listen('preventDragEvent', function(e, isDown, preventObj) {
preventObj.prevent = true;
});
I also tried the 'isClickableElement' option, but that doesn't seem to help, either...
This method isn't ideal, but if you're looking to disable swiping/dragging without having to use a modified version of PhotoSwipe, this worked for me:
var allowSwipe = false;
function preventSwipe (e) {
if (!allowSwipe) {
e.preventDefault();
e.stopPropagation();
}
}
pswp.container.addEventListener('pointerdown', preventSwipe);
pswp.container.addEventListener('MSPointerDown', preventSwipe);
pswp.container.addEventListener('touchstart', preventSwipe);
pswp.container.addEventListener('mousedown', preventSwipe);
Or if you're using jQuery:
var allowSwipe = false;
$(pswp.container).on('pointerdown MSPointerDown touchstart mousedown', function () {
return allowSwipe;
});
Using the allowSwipe variable, you can re-enable swiping at any point by setting it to true.
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 :)
Introduction:
Hello everyone. I am trying to do a menu, but i have problem with mouseenter/mouseleave events.
What i have so far:
$("#icon").click(function() {
$("#invis").css("display", "block");
$("#icon").bind("mouseleave", function(){
$("#invis").css('display', "none");
}).bind("mouseenter", function(){
$("#invis").css('display', "block");
});
$("#invis").bind("mouseleave", function(){
$("#invis").css('display', "none");
}).bind("mouseenter", function(){
$("#invis").css('display', "block");
});
});
So far, i tried this. My point is to click on the "icon", and this click would show a menu/another, hidden element. Now i want to keep it open as long, as someone keeps mouse over "icon" or actual menu. But with code i provided, once i leave my mouse and then enter again on "icon", it still keeps onmouseenter event, and menu will appear again. I know i could unbind onmouseenter event, but then once i drive off menu, onto icon, my menu would get closed, and i don't want that.
Simplest example i could think of: http://jsfiddle.net/tzzqM/5/
Question
How to make "menu" open on click event, and then keep it open as long as someone keeps mouse over menu or "icon" (both of them). Once mouse leaves area of both, menu closes, and to open it i need to click once more on "icon".
Is there a another way to do this?
On mouse leaving the object, check if the mouse is still either on the menu or on the menu-button, if not, hide the menu. Basically, you're binding the event mouseleave to both elements and then checking the length of the selection. If it's 1, you're either on the menu or the button, this makes the exiting the menu button into the menu itself, not trigger the "hidding" part of the code, if the selection length is 0, then we are not over any of those elements and we hide it.
$("#icon").click(function() {
$("#invis").css("display", "block");
$("#invis,#icon").bind("mouseleave", function(){
if($("#invis:hover,#icon:hover").length === 0){
$("#invis").css('display', "none");
}
})
});
There's a fiddle here.
Or the way I would write it if I had to start from scratch (just the jQuery part), since remember that you'd be jumping into the DOM pool less times and should be a little bit more efficient, although it's as functional as the first one. Here's the fiddle
var icon = $("#icon"),
menu = $("#invis");
icon.click(function() {
menu.show();
$.merge(icon,menu).bind("mouseleave", function(){
if($("#icon:hover,#invis:hover").length < 1) menu.hide();
});
});
Or using the suggestion from jhummel we can access the id of the new view that has the hover, and check if it's one of the two that we want to monitor. This is great because it prevents us from jumping into the pool once more, this gives us a marginal performance boost, here's the fiddle.
var icon = $("#icon"),
menu = $("#invis");
icon.click(function() {
menu.show();
$.merge(icon,menu).bind("mouseleave", function(e){
if($.inArray(e.relatedTarget.id, ["icon","invis"]) === -1){
menu.hide();
}
});
});
Related docs:
jQuery.merge
Stop jumping into the pool!
jQuery.inArray
event.relatedTarget
When you use mouseover or mouseleave events, the event object in jQuery will have a relatedTarget property. You can check that property to see if the mouse is entering the other element.
$("#icon").on('click',function() {
$("#invis").show();
}).on('mouseleave', function(e) {
if(e.relatedTarget.id != 'invis') $('#invis').hide();
});
$('#invis').on('mouseleave', function(e) {
if(e.relatedTarget.id != 'icon') $(this).hide();
});
jquery relatedTarget docs
My jQuery code:
$('.box_class').bind('mouseover', function(e){
$('.tooltip').css({'top':e.pageY,'left':e.pageX, 'z-index':'1'});
$('.tooltip').fadeIn("fast");
});
It works fine, but I want that message would always follow the mouse pointer and now, when I "mouseover" on box_class it always stays at the same point. I probably should change mouseover function to another? Or how should I implement that?
Try mousemove:
$('.box_class').bind('mouseover', function(e){
$('.tooltip').fadeIn("fast");
});
$('.box_class').bind('mousemove', function(e){
$('.tooltip').css({'top':e.pageY,'left':e.pageX, 'z-index':'1'});
});
Keep your mouseout or mouseleave observer to close the tooltip.
Is the position set to absolute? If not try:
position:absolute;
I have a draggable object, with that can be accepted in several droppables.. I have put all the droppables in a container, and simply want to be able to detect when the draggable is hovering over the container of droppables...
At first, I tried making use of the 'over' and 'out' callbacks for droppables, but it was not working because hovering from one droppable to another (inside the same container) was causing it to think the mouse had left the container...
So my next approach was to in the drag start callback, do an event listener for mouseenter and mouseleave on the container-- and then stop listening on the drag stop callback...
However, this results in total crazy behavior... If you look at my example page:
http://collinatorstudios.com/www/jquery_draggable_test.html
When dragging the box to the red dropzone, you should see "enter" when the mouseenter event fires, and "leave" when mouseleave happens.. However, just dragging the box over the inside of the container causes "leave" to appear a zillion times..... I cannot figure out why this is happening, nor what solution there is to my problem so I can do what I need to. I've been working on this for almost 4 hours now and am losing my mind over what seems like it should be so simple to achieve.
Any help would be greatly appreciated... Thanks.
Try adding a droppable for the container:
$('#drop_zone_container').droppable({
over: function(){ feedback.text('enter')},
out: function(){feedback.text('leave')}
});
You only need to bind to the events once! There is no need to bind and unbind them each time... I separated them out in the code below to make it more clear about binding once.
And as ZDYN said (+1 to him), you need to include a droppable code, but instead of using the container, use the zones inside... here is a demo and the full code below.
var feedback = $('#feedback');
$('.item').draggable({
revert: true,
zIndex: 999,
cursor: 'move'
});
$('.drop_zone').droppable({
drop: function(event, ui) {
ui.draggable.appendTo($(this));
}
}).bind('dropover dropout', function(e) {
var id = this.id;
feedback.text(e.type === 'dropover' ? 'Over: ' + id : 'Out: ' + id);
});