I use the following javascript (with jQuery) to handle drag and drop on a script I am writing:
jsc.ui.dragging = false;
jsc.ui.drag_element = {};
$(".drag-target").mousedown(function() {
jsc.ui.drag_element = $(this);
jsc.ui.dragging = true;
});
$("html").mousemove(function(e) {
if(jsc.ui.dragging) {
jsc.ui.drag_element.css({"position": "absolute", "top": e.clientY - 1, "left": e.clientX - 1, "z-index": "100"}); // - 1s are due to IE not leaving go otherwise
$("#overlay").show(); // Overlay stops text beneath being selected. TODO Stop current elements text being selected.
}
});
$(".drag-target").mouseup(function() {
if(jsc.ui.dragging) {
jsc.ui.dragging = false;
jsc.ui.drag_element.css("z-index", "98");
$("#overlay").hide();
}
});
However when the object is being dragged, the text inside it has a flickering selection i.e. it is being selected on and off as the element is moved. Is there any way to prevent this, or hide it's effect?
Is there a reason for not using jQuery UI Draggable ? Your code would look like that:
$(".drag-target").draggable();
You should at least check how it's build, it may help you to solve you flickering problem.
I think the extent of the effect depends on your hardware and video driver. To avoid it entirely, you could just draw a rectangle and then redraw the window when the mouse button is released.
Related
Images can explain better than words sometimes.
So I've a very weird problem with my self-written jquery tooltip (I actually want to avoid to use some lib, since my use-case is actually pretty simple and I don't need some bloated lib here).
When I move my mouse from right to left or from top to down everything is fine. When I move my mouse from left to right or bottom to top my tooltip gets stuttering - see the gif.
My tooltips are referenced by data attributes
HOVER ME
<div id="myTooltip">Tooltip Content Foo Bar</div>
To avoid problems positioning my element I'll move it later wit jQuery to the body.
Well, now I've now idea whats going on with my tooltip. Any ideas why it is stuttering?
BTW: This is happening in all modern browsers for me.
$(function () {
$('[data-tooltip]').each(function () {
$($(this).data('tooltip')).appendTo('body');
// this mouseenter listener could be safely removed, probably
// (don't forget to move the display:block part to mousemove tho)
$(this).on('mouseenter', function (e) {
$($(this).data('tooltip')).css({
display: 'block',
left: e.pageX,
top: e.pageY
});
});
$(this).on('mousemove', function (e) {
$($(this).data('tooltip')).css({
left: e.pageX,
top: e.pageY
});
});
$(this).on('mouseleave', function () {
$($(this).data('tooltip')).hide();
});
});
});
I think I found a solution for you. Might not really what you wanted but I think it will work for what you want to use it for.
Here is the JSfiddle: http://jsfiddle.net/nj1hxq47/3/
Ok so the key is to make sure the mouse never goes over the element you are dragging. So making sure you have at least 1 xp between the element you are dragging and the element you are hovering over will make sure it does not trigger the onleavemouse event.
var yPos = e.pageY + 5;
I am sure there is a better way to do this... but I hope this helps.
EDIT: The main problem is the mouse is going over the element you are moving to the mouse's position and thus triggering the onmouseleave event resulting in the element being hidden and shown in milliseconds of each other. Because the mouse leave event triggers before the move.
Is it possible to slow down the speed of a draggable element?
I have build a simple slider with jQuery drag and drop. When the slider element (the draggable element) moves to certain positions a picture fades in. So if you move the draggable element not too fast it looks like you can handle a "picture animation" with the slider. Now, I want to slow down the draggable element. So the user never can drag the element too fast.
This is an example of my code.
$('.slider').mousemove(function(){
if($(this).position().left >= 0 && $(this).position().left <= 2 ) {
$('.slider_1').fadeIn();
$('.slider_2').fadeOut();
}
...
I hope someone can help me :)
Ah! finally an interesting jQuery question.
This can definitely be achieved. Below I've explained how. If you want to go straight to the demo, click here.
Let's assume your HTML is setup as follows:
<div id="slider">
<div id="bar"></div>
</div>
Where the bar is the actual thing you click and drag.
Now what you need to do is the following:
get the $('#bar').offset().left
explicitly specify the position of #bar when the draggable is dragged, using some extra variable SPEED
For example:
ui.position.left += (ui.offset.left - ui.originalPosition.left - leftOffset)*SPEED;
Then, you can use the $('#bar').offset().left in jQuery's .fadeTo() (or other) function to change the opacity of the image you are talking about.
This all seems rather trivial, but it's not. There are some problems when trying to implement this. For example:
When the slider reaches the maximum sliding distance, it should stop animating or be reset. You can do this in multiple ways but I think the easiest solution is to write a .mousedown / .mouseup listener which updates a variable dragging, that keeps track whether the user is still trying to drag #bar. If it's not, reset #bar. If it is, keep the slider at the maximum distance until .mouseup is fired.
Also, you must be careful with predefined borders.
The code I propose is the following:
// Specify your variables here
var SPEED = -0.6;
var border = 1; // specify border width that is used in CSS
var fadeSpeed = 0; // specify the fading speed when moving the slider
var fadeSpeedBack = 500; // specify the fading speed when the slider reverts back to the left
// Some pre-calculations
var dragging = false;
var slider = $('#slider');
var leftOffset = slider.offset().left + border;
var adjustedSliderWidth = 0.5*slider.width();
// the draggable function
$('#bar').draggable({
axis: "x",
revert : function(event, ui) {
$(this).data("draggable").originalPosition = {
top : 0,
left : 0
};
$('#image').fadeTo(fadeSpeedBack, 0);
return !event;
},
drag: function (event, ui) {
var barOffset = $('#bar').offset().left - leftOffset;
if (barOffset >= 0) {
if (barOffset < adjustedSliderWidth) {
ui.position.left += (ui.offset.left - ui.originalPosition.left - leftOffset)*SPEED;
} else {
if (!dragging) { return false; }
else { ui.position.left = adjustedSliderWidth; }
}
}
// fading while moving:
$('#image').fadeTo(fadeSpeed, (ui.position.left/adjustedSliderWidth));
// remove this if you don't want the information to show up:
$('#image').html(ui.position.left/adjustedSliderWidth
+"<br \><br \>"
+ui.position.left);
}
});
// the mouse listener
$("#bar").mousedown(function(){ dragging = true; });
$("#bar").mouseup(function(){ dragging = false; });
I've also implemented the revert option on draggable so the slider nicely returns to zero when the user releases #bar. Of course you can delete this if you want.
Now the variable that your whole question is about is the variable: SPEED.
You can specify the speed of dragging by specifying a number for this variable.
E.g.:
var SPEED = 0.0; // the normal dragging speed
var SPEED = 0.5; // the dragging speed is 1.5 times faster than normal
var SPEED = -0.5; // the dragging speed is 0.5 times faster than normal
So negative values give a slower dragging speed and positive values give a faster dragging speed.
Unfortunately (or actually: fortunately), it is not possible to change the speed of the mouse pointer. This because only the OS has control over the mouse coordinates and speed. Browsers cannot influence this. Personally I think it doesn't matter: moving the slider slower than normal is what you're trying to achieve, so you can ignore the mouse pointer.
To see all this in action, I've prepared a working jsFiddle for you:
DEMO
I hope this helps you out :)
I have some uncommon wishes about scrolling in the page I'm making. I already tried a lot of things, but those aren't working like they should. All I want is that when people use their scroll wheel (wherever their cursor stands) the search-results are scrolling.
I've uploaded my result so far at http://www.veylau.be/testzone/scrollfix/searchtwee.html
Just click the search button to see the dummy results.
Problems:
1) With the script I'm using now I'm having a sort of a parallax effect. I just want the results to scroll, not the rest of the page.
2) When the rest of the page is done scrolling, it isn't possible to scroll through anymore.
3) is it possible to catch the scroll-event when the cursor is over the #googleMap or the #mapContainer div? I tried like this, but only the second one is executing.
$("#mapContainer").scroll(function(event){...});
$(window).scroll(function(event){...});
Thank you very much for your help guys!
You can catch the $(window).scroll(function(event){...}); and inside this function check if the mouse is hover the mapContainer with the check if($("#mapContainer:hover").length>0)
You can do something like tracking the mouse movement , and when scroll occurs setting the position to the last known position
I have tried a sample, Here is my code , Not perfectly refined. still i think this may help
var MouseposX;
var MouseposY;
$(window).bind("mousemove", function (event) {
MouseposX = event.pageX;
MouseposY = event.pageY;
});
$(window).scroll(function (event) {
placeDiv(MouseposX, MouseposY);
});
function placeDiv(x_pos, y_pos) {
var d = document.getElementById('searchResults');
d.style.position = "absolute";
d.style.left = x_pos+'px';
d.style.top = y_pos+'px';
}
Check the fiddle
http://jsfiddle.net/46WLt/3/
I have make a div in the right of the screen. First you have a a href. You can drag this div open with this button. Here is a example: Here Right in the screen you see the "Wat is een delicous tasting" button. You can drag it open.
But i have problems with this. This are the problems:
The biggest problem. When you drag the div open. And than you drag the div back. You can drag the div outside the screen. But the is not good. When you closed the div. You can not drag it out the screen.
How can i fadein the overlay. The overlay must be smooth. Now it is not pretty.
How can i make a bounce effect in the box.
I am an beginning javascripter. I hope you can help me with this!! Thanks for helping!
You can change the code on jsFiddle: jsfiddle
Add a condition test to check whether the mouse position exceeds a certain boundary or not. If the mouse go past a fixed limit (window width - element's width), don't change the right attribute of the marker.
Fiddle: http://jsfiddle.net/ErWjr/1/
$(function () {
"use strict";
var box = $(".what-is-delicious"),
button = $(".what-is-delicious > a"),
mouseDown = false,
grabbed = 0,
start = -303,
maxLeftOffset = $(window).width() - 75;
// ^^^ Limit to 75px from the right (= marker's width)
button.mousedown(function (e) {
mouseDown = true;
$('*').bind('selectstart', false);
grabbed = e.pageX;
button.css({ cursor: "-moz-grabbing"});
$("body").append('<div class="background-overlay"></div>');
});
$('body').mouseup(function () {
mouseDown = false;
$('*').unbind('selectstart', false);
button.css({ cursor: "-moz-grab"});
$(".background-overlay").remove();
start = parseInt(box.css('right'), 10);
}).mousemove(function (e) {
if (mouseDown) {
if(e.pageX > maxLeftOffset) return; //<---- Don't go past an edge
//button.addClass("open");
box.css("right", Math.min(grabbed - e.pageX + start, 0));
}
});
});
Well, it looks like you are trying to emulate dragging rather than using the plugin designed for the purpose. Try this:
http://jqueryui.com/demos/draggable/
There are a bunch of demos there, one of those should sort you out.
See this demo page in iphone http://jsbin.com/unese4/8 at the bottom of the page there is one dropdown which opens but doesn't work properly.
This question is related to this question iScroll 4 not working with form <select> element iPhone Safari and Android browser
Actually, your issue is related to this question:
webkit-transform issue on safari using select elements
When an input gains focus in iOS Safari, it checks if the input is in view. If it isn’t, Safari forcibly scrolls the document, and the element(s) which contain the input, to make it visible.
iScroll uses a CSS transform to move the scrollable area around, and it looks like Safari’s behavior is broken for selects — it doesn't notice the transform, thinks that the select is out of view, and scrolls its container (#scrollable) to make it visible (again, not accounting for the transform), which puts it way out of view.
This is fundamentally an iOS bug, and should be reported to Apple by as many web developers as are affected by the issue! A workaround can be implemented most effectively inside iScroll, so I encourage you to report the issue to its developers.
That said, I have come up with a workaround, which you'll find at the bottom of this answer. You can use it by calling it, once, with your instance of iScroll:
workAroundiScrollSelectPositioning(myScroll);
A live demo is at your jsbin paste here. It triggers when a select gains focus, and does three things:
Remembers the scroll position, and tells iScroll to immediately scroll to the top left corner (removing any transform), and sets the top and left CSS properties of the scroll area to the current scroll position. Visually, everything looks the same, but the scroll area is now positioned in a way that Safari will see.
Block iScroll from seeing any touches (this is ugly, but it stops iScroll from applying a transform on the scroll area while we have it repositioned).
When the select loses focus, put everything back to the way it was (restore the original position and transform and stop blocking iScroll).
There are still cases where the element's position can get screwed up (e.g. when a textarea has focus but is only partially in view, and you type and cause Safari to try to bring the rest of it in view), but these are best fixed in iScroll.
function workAroundiScrollSelectPositioning(iscroll){
iscroll.scroller.addEventListener('focusin', function(e){
if (e.target.tagName === 'SELECT') {
var touchEvent = 'ontouchstart' in window ? 'touchmove' : 'mousemove',
touchListener = {
handleEvent: function(e){
e.stopPropagation();
e.stopImmediatePropagation();
}
},
blurListener = {
oldX: iscroll.x,
oldY: iscroll.y,
handleEvent: function(e){
iscroll.scroller.style.top = '';
iscroll.scroller.style.left = '';
iscroll.scrollTo(this.oldX, this.oldY, 0);
e.target.removeEventListener('blur', blurListener, false);
iscroll.scroller.removeEventListener(touchEvent, touchListener, true);
}
};
iscroll.scroller.style.top = iscroll.y + 'px';
iscroll.scroller.style.left = iscroll.x + 'px';
iscroll.scrollTo(0, 0, 0);
e.target.addEventListener('blur', blurListener, false);
iscroll.scroller.addEventListener(touchEvent, touchListener, true);
}
}, false);
}
you can use a custom table view on that place, suppose you want to show drop down list when user click on textfield.
so when the user clcik on the textfield the delegate method get called TextFieldBeginEditing and inside that create a small table view . that look like a drop down list ...
This is modified function workAroundiScrollSelectPositioning that worked for me.
function workAroundiScrollSelectPositioning(iscroll){
var touchEvent = 'ontouchstart' in window ? 'touchstart' : 'mousemove',
oldX, oldY;
iscroll.scroller.addEventListener('focusin', function(e){
if (e.target.tagName === 'SELECT') {
var blurListener = {
oldX: oldX,
oldY: oldY,
handleEvent: function(e){
iscroll.scroller.style['margin-top'] = '';
iscroll.scroller.style.left = '';
iscroll.scrollTo(oldX, oldY, 0);
e.target.removeEventListener('blur', blurListener, false);
}
};
iscroll.scroller.style['margin-top'] = oldY + 'px';
iscroll.scroller.style.left = oldX + 'px';
iscroll.scrollTo(0, 0, 0);
e.target.addEventListener('blur', blurListener, false);
}
}, false);
iscroll.scroller.addEventListener(touchEvent, {
handleEvent: function(e){
if (e.target.tagName === 'SELECT') {
oldX = iscroll.x,
oldY = iscroll.y;
e.stopPropagation();
e.stopImmediatePropagation();
}
}
}, true);}