Hover like effect while dragging - javascript

I want to make a "hover" like effect while dragging an object over other objects. The objects that can be hovered is inside an iframe while the object the user can drag is outside the iframe. This fiddle illustrates what i am trying to do: http://jsfiddle.net/9yyKN/14/
$("#ha").draggable({
drag: function () {
$(".box").each(function() {
$(this).removeClass("under");
if (event.pageX > $(this).position().left
&& event.pageX < ($(this).position().left + $(this).width())
&& event.pageY > $(this).position().top
&& event.pageX < ($(this).position().top + $(this).height()) )
{
$(this).addClass("under");
}
});
}
});
The boxes should have a little inset shadow when i am dragging the "ha" box over them (the "under" class). I tried do compare their position with the cursor position, but it didn't end up working very well.
The iframe also have a div over it so i can drag objects over it without the drag effect going weird. But because of that :hover, .mouseover() etc. won't work. I have not put an iframe in this fiddle though. I just tried to simplify my problem.
Any ideas for making this work?

You have a small mistake your condition should be:
if ( event.pageX > $(this).position().left
&& event.pageX < ($(this).position().left + $(this).width())
&& event.pageY > $(this).position().top
&& event.pageY < ($(this).position().top + $(this).height()) )
Have a look here: http://jsfiddle.net/straeger/fggKn/
Here is a more precisely version http://jsfiddle.net/straeger/TbwAT/1/

Related

Scrolling based on mouse position retaining click events in the foreground

So I have a very wide div within a smaller div. The inner div scrolls left and right depending on mouse position.
I adapted the code from this answer... https://stackoverflow.com/a/6137535/3656408
There are two transparent divs on top of everything, from which the position of the mouse is attained, which gives a speed at which to scroll.
The problem with this is anything underneath these divs is not clickable.
My div has a fixed width and height so I potentially could calculate the scroll speed from where the mouse is on the page ( ie. the page is 620px wide so I know 310 is half way )
Unfortunately my maths is terrible and I can't figure out how to convert my thought process into acceptable working code.
Anyone have any suggestions?
Heres how it currently figures out the rate at which to move the page...
$('.direction', backdrop).mousemove(function(e){
var $this = $(this);
var left = $this.is('.left');
if (left){
var w = $this.width();
rate = (w - e.pageX - $(this).offset().left + 1)/w;
}
else{
var w = $this.width();
rate = -(e.pageX - $(this).offset().left + 1)/w;
}
});
.. and you can see it in action here http://thetally.efinancialnews.com/tallyassets/20years/index.html
OK I figure it out...
$( document ).mousemove(function(e){ //if mouse moves on page
if (e.pageX <= 620 && e.pageY <= 600){ //and if its not outside the extents of the div
if (e.pageX <= 310){ //if its less than half way across
rate = (310 - e.pageX)/50;
} else { // if its more than half way across
rate = -( e.pageX - 310)/50;
}
}
});

AngularJS - draggable bootstrap modal

I am using an AngularJS directive for modals, to make them draggable.
This is the directive.
In the demo, you can clearly see that if you drag it (especially left and right) it is slower than your mouse. I understand why this happens (the JavaScript calculates position relative to it's starting position, so in my 1920x1080 screen it goes from -1200px to 1920px on the x axis). And I understand there is a need to use offset instead of position, but after many tries I failed to make it that.
This is the relevant JavaScript code:
element.on('mousedown', function (event) {
// Prevent default dragging of selected content
event.preventDefault();
startX = event.screenX - x;
startY = event.screenY - y;
$document.on('mousemove', function mousemove(event) {
y = event.screenY - startY;
x = event.screenX - startX;
element.css({
top: y + 'px',
left: x + 'px'
});
});
});
How can I make it rely on the offset and move together with the mouse and not slower?
Try this one: http://plnkr.co/edit/QxIdGj . I have hardcoded 2 values, which you shouldn't do. Your "mistake" was that you were putting the draggable directive in the wrong element. I added the draggable directive to <div class="modal-content"> which is what I believe is the element that you want moved.
I also changed your element.css({ to
element.css({
top: event.clientY - 30 + 'px',
left: event.clientX - 10 + 'px'
});
It's using .clientX/Y which is the actual position of the mouse, without the need of further calculations.

Limit vertical background position on scrolling with jQuery

I'm using this function:
$(window).bind('load resize scroll',function(e) {
var y = $(window).scrollTop();
$('.tm-parallax').filter(function() {
return $(this).offset().top < (y + $(window).height()) &&
$(this).offset().top + $(this).height() > y;
}).css('background-position', '50% ' + parseInt(-y / 50) + 'px');
});
to achieve parallax effect on background images when scrolling down.
I would like to limit y position to certain value (for example 100px), so background image center stays visible after reaching this value.
Here is the code: http://jsfiddle.net/esedic/vw2n16r8/4/
Because bakcground images are quite large it's best seen on fullscreen: https://jsfiddle.net/esedic/vw2n16r8/4/embedded/result/
Because I'm using parallax background images on multiple elements, I'm looking for solution to set different values for each element (maybe using data attributes?).
Thanks for your help!
You should try reversing its polarity, but try this:
$(window).bind('load resize scroll',function(e) {
var y = $(window).scrollTop();
$('.tm-parallax').filter(function() {
if have return $(this).onset().top < (y + $(window).height()) &&
$(this).onset().top + $(this).height() > y;
}).css('background-position', '50% ' + parseInt(-y / 50) + 'px');
});

Jquery - techniques for extending 'perimeter' for mouseout?

I would like to implement behaviour such that a mouseover/hover event is triggered when the mouse pointer hovers over a certain div, but such that the mouseout event tiggers not when the pointer leaves the div, but when it leaves the area 10px ourside the div.
Is there any way of achieving this that doesn't involve creating a larger parent div to bind the mouseout event to?
My comment got me interested to see if it was possible and it's actually quite easy. No idea how well it would run in different browsers and with lots of divs but it works in this example:
http://jsbin.com/exulef/2/edit
var hello = $('#hello');
var position = hello.offset();
var height = hello.height();
var width = hello.width();
$(document).mousemove(function(e) {
if (hello.data('inside')) {
if ((e.pageX < position.left - 10 || e.pageX > position.left + width + 10) ||
(e.pageY < position.top - 10 || e.pageY > position.top + height + 10)) {
hello.text(position.top + " : " + position.left + " : " + e.pageX + " : " + e.pageY + " Outside")
.data('inside', false);
}
}
else {
if ((e.pageX > position.left && e.pageX < position.left + width) &&
(e.pageY > position.top && e.pageY < position.top + height)) {
hello.text(position.top + " : " + position.left + " : " + e.pageX + " : " + e.pageY + " Inside")
.data('inside', true);
}
}
});
hello is just a square div. Would be quite easy to turn into a plugin as well which I might do later, lol.
Edit - I did make this into a plugin in the end: http://jmonkee.net/wordpress/2011/09/07/jquery-extended-hover-plugin/
There is a way to do that without an external div, but it imply that your div will have a margin even when not hovered.
It uses the fact that the padding is inside the div, and the margin is outside.
When nothing happens, we have a margin, we have to go inside the div to hover.
When it's hovered, the margin becomes padding, this way we're inside the div for a little bit more when the mouse leaves the div.
When we're leaving the padding, it's back to margin.
The css is something like:
.a{
margin:10px;
}
div.b{
padding:10px;
margin:0;
}
Note that it's important to have a b selector that's a bit more specific in order to have it apply without using important and without taking attention of the order.
The js would be:
$(".a").bind("mouseenter",function(){
$(this).addClass("b");
}).bind("mouseleave",function(){
$(this).removeClass("b");
});
Example here: http://jsfiddle.net/ynecV/
Hmm, I would go with wrapping desired div in another one and binding mouseout on it - it would be most reliable solution.
BUT, if you insist on not creating another div, then I would bind custom mousemove handler that would be binded (on document) on mouseenter over div, and would detect the fact that mouse move away from div bounding box for more than 10px. If so, mousemove handler would fire custom jQuery event and then it would unbind itself.

Detect when mouse leaves via top of page with jquery

This Jquery problem has been bugging me for a while now. I developed a script, with one function detecting when the mouse leaves via the top of the page. Here is the code:
$(document).bind("mouseleave", function(e)
{
console.log(e.pageY);
if (e.pageY <= 1)
{
now = new Date();
for (i=0; i < times.length; i++)
{
if (now.getTime() > times[i][0] && now.getTime() < times[i][1])
{
$.fn.colorbox({iframe:true, width:650, height:600, href: "work.html", open: true});
}
}
}
});
This works perfectly for me in all browsers. For some reason it works randomly in Chrome and seemingly not at all in Firefox for a friend that tested the site. In my browser (firefox 3.5.3), e.pageY is logged in the console box as a number near 0, however in my friends browser (also firefox 3.5.3) the lowest value is around 240. I have no idea why this is happening considering identical browsers. Does anyone have a clue as to how to debug this, or another more reliable method to detect when the mouse goes out of the webpage via the top? I hope this makes sense.
The problem appears if your window scrolls down, add a bunch of <br/>s to your page and scroll down one line and you'll see it.
So instead of looking to see if e.pageY <=1, subtract out the scrollTop:
if (e.pageY - $(window).scrollTop() <= 1)
{
// do something
}
I used another technic, almost works for all browsers. The trick is using $("body") or $(window).
$(window) do not work for IE, but $("body") works partially for FF as the body might not fill the whole window.
Here's the full page code:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script><script>
var mouseX = 0;
var mouseY = 0;
var theFrame;
$(function() {
theFrame = $("body"); //$(window) for non-IE
theFrame.mousemove( function(e) {
//horizontal distance from edge
mouseX = Math.min(theFrame.width() - e.pageX, e.pageX);
//vertical distance from top
mouseY = e.pageY;
$("#mx").html(mouseX);
$("#my").html(mouseY);
});
theFrame.mouseout(function() {
if(mouseY<=mouseX)
$("#in_out").html("out-top");
else
$("#in_out").html("out");
});
theFrame.mouseover(function() {
$("#in_out").html("in");
});
});
</script>
</head>
<body>
<span id="in_out"></span>
<br />Hor: <span id="mx"></span>
<br />Ver: <span id="my"></span>
</body>
</html>
$(document).on('mouseleave', leaveFromTop);
function leaveFromTop(e){
if( e.clientY < 0 ) // less than 60px is close enough to the top
alert('y u leave from the top?');
}
This doesn't work well on older IE version, because those versions don't report the mouse position as should, but it's good enough.
Here is a vanilla JS solution if you just want something light weight that doesn't need to work in EI
/**
* Trigger an event when the cursor leaves the top of the window
* #param {*} threshold how close does it need to be to the top
* #param {*} cb callback function to trigger
*/
function onExit (threshold, cb) {
threshold = threshold || 60
var hasExited = false
document.addEventListener('mouseout', function (e) {
if (e.clientY < threshold && e.movementY < 0 && !hasExited) {
hasExited = true
cb(e)
}
})
}
Example Usage:
onExit(20, function() {
console.log('Mouse has left the top of the window!')
}
In order to detect mouseleave without taking in account the scroll bar and the autcomplete field or inspect :
document.addEventListener("mouseleave", function(event){
if(event.clientY <= 0 || event.clientX <= 0 || (event.clientX >= window.innerWidth || event.clientY >= window.innerHeight))
{
console.log("I'm out");
}
});
Conditions explanations:
event.clientY <= 0 is when the mouse leave from the top
event.clientX <= 0 is when the mouse leave from the left
event.clientX >= window.innerWidth is when the mouse leave from the right
event.clientY >= window.innerHeight is when the mouse leave from the bottom
Just keep
event.clientY <= 0
If you only want to detect exit on top

Categories

Resources