I'm currently working on a small project, with draggable divs. The code I've created seems to not be working, and it causes JQuery to stop responding.
Is there a nice and easy way to do this without using .draggable?
var hold = false;
//Drag Elements
$('#example').mousedown(function(){
hold = true;
});
$('#example').mouseup(function(){
hold = false;
});
$(document).on('mousemove', function(e){
$('#example').css({
while(hold){
left: e.pageX-50,
top: e.pageY-50
}
});
});
Thanks
Since Javascript is single-threaded, your while loop never exits, because the mouseup handler can't run while you're stuck in the mousemove handler.
Change while to if:
$(document).on('mousemove', function(e){
if (hold) {
$('#example').css({
left: e.pageX-50,
top: e.pageY-50
});
}
});
Related
I am getting familiar with jQuery and making a little application where a red box moves around the screen and the user has to try and click on it and when the user does an alert() box pops up but the problem is that the alert() keeps popping up even after 'ok' is pressed. The only way I can stop it is to repeatedly click 'ok' and eventually it goes away.
Here is the code that displays the alert box:
function Animate() {
var _newPosition = GetNewPosition();
// Sets new position of div
div.animate({
top: _newPosition[0],
left: _newPosition[1]
}, function () {
div.on('click', function () {
alert('You clicked the box!');
});
Animate();
});
}
Here is my JSFiddle that reproduces the problem
I originally thought that I could solve it by returning false after the call to the alert() for example:
div.on('click', function () {
alert('You clicked the box!');
return false;
});
But that didn't work either.
I know this should be a simple thing to figure out but I cant quite seem to get my thumb on it.
The click handler is recursively called in the animation complete callback which is binding the click event on the element multiple times. So, when the element is clicked the handler is being called multiple times.
To solve the issue, bind the event only once.
function Animate() {
var _newPosition = GetNewPosition();
// Sets new position of div
div.animate({
top: _newPosition[0],
left: _newPosition[1]
}, Animate);
}
And in ready()
$(document).ready(function () {
Animate();
div.on('click', function() {
// Code here
alert('clicked');
});
});
Using Animate as reference to the animation complete callback is same as
function() {
Animate();
}
The function reference will be passed to the animate and it'll be called when the animation is completed.
Suggestions:
Use mousedown event to track the click on moving object
Use random duration for animate.
FIddle
var div = $('#box');
$(document).ready(function() {
Animate();
div.on('mousedown', function() {
// Code here
console.log('clicked');
});
});
function GetNewPosition() {
// Get dimentions of the window and remove the div area
var h = $(window).height() - 50;
var w = $(window).width() - 50;
// New height and width is auto generated
var nh = Math.floor(Math.random() * h);
var nw = Math.floor(Math.random() * w);
return [nh, nw];
}
function Animate() {
var _newPosition = GetNewPosition();
// Sets new position of div
div.animate({
top: _newPosition[0],
left: _newPosition[1]
}, (Math.floor(Math.random() * 5000) + 1), Animate);
}
#box {
width: 50px;
height: 50px;
background-color: red;
position: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3 id="success"></h3>
<div id="box"></div>
Event is getting bound multiple times as it is in animate function. Instead binding click event in animate bind it in $(document).ready(function () {}); so that it will only get bound once.
Please find updated jsfiddle
I tried to do some animation with click function button and left/right arrow keyboard, just a simple left-right sliding animation. At first those script works perfectly, til I edit here and there, but not these JS.
When I run it again, only the keyboard based animation works, the button click animation wont work anymore.
$(document).ready(function(){
$('.btnright').click(function(){
$('.project').animate({
left: '-=150px',
});
});
$('.btnleft').click(function(){
$('.project').animate({
left: '+=150px',
});
});
});
I do test the the click function with alert, but the alert wont work too.
$(document).ready(function(){
$('.btnright').click(function(){
alert('right');
});
$('.btnleft').click(function(){
alert('left');
});
});
And I already check if I used the wrong class, but now, it's just allright.
<div class="btnright"><span class="material-icons">keyboard_arrow_right</span></div>
<div class="btnleft"><span class="material-icons">keyboard_arrow_left</span></div>
Here are the keyboard animation script, this keyboard script works fine
$(document).on("keydown", function(event) {
var x = event.keyCode;
if (x == 37) { // left
$('.project').animate({
left: '+=150px',
});
} else if (x == 39) { // right
$('.project').animate({
left: '-=150px',
});
}
});
Maybe I'm missing something. I'll appreciate for ya'll help. Thx.
Remove the trailing comma from your options object. Also, you need to specify the duration for the animation. Also, .project would need to be absolutely or relatively positioned (instead of default of static) for left to have an effect. So:
$('.btnright').click(function(){
$('.project').animate({
left: '-=150px'
}, 500);
});
With CSS:
.project {
position: relative;
}
Instead of:
$('.btnright').click(function(){
$('.project').animate({
left: '-=150px',
});
});
Codepen: http://codepen.io/anon/pen/WQzazR
I'm using jQuery 191 and Hammer JS 204. I have the following example scenario
<div> class="myDiv">
<div class="content">
<img>
</div>
</div>
Example JS
$('.myDiv').hammer({}).bind("pan", function(h) {
h.gesture.srcEvent.preventDefault();
});
$('.content img').on('click', function(){
console.log('i was clicked');
});
When I click on the image to start panning myDiv, Right after panend, the myDiv img click event gets fired.
I've tried to stopPropagation and stopImmediatePropagation but still couldn't get it to stop firing the click after i finish panning.
var hammering = false;
$('.myDiv').hammer({}).bind("pan", function(h) {
h.gesture.srcEvent.preventDefault();
}).bind("panstart", function(h) {
hammering = true;
}).bind("panend", function(h) {
setTimeout(function(){
hammering = false;
}, 300);
});
$('.content img').on('click', function(){
if(hammering) return false;
console.log('i was clicked');
});
Another way to avoid this ghost click is to create a pseudo class over the hammer target.
for example you can add class and the style something like
`.block:after {
content: " ";
background: transparent;
top: 0;
left: 0;
width: 250px;
height: 100%;
z-index: 2;
display: block;
position: absolute;
}`
when panstart and remove it when panend.
hope this trick will help others.
I find out a easy way could prevent click event while hammer.js panning:
disable div pointer-events while pan start, then enable it while pan end.
...
myPanGesture.on("panstart", function(ev) {
$(".tab-pane.active").css({'pointer-events':'none'});
});
...
myPanGesture.on("panend", function(ev) {
$(".tab-pane.active").css({'pointer-events':'auto'});
});
...
how to show toolbar (and hide current) when i click on next similar element? in my code, when i click on next similar element, toolbar doesn't disappear, he disappears only if i firsly click on body and then on element, how to remove toolbar without clicking to body to show next toolbar? thx!
http://jsfiddle.net/wwL8fgr1/1/
$(".element").on('mouseup', function(e){
$('[el-button]').click(function(e){
e.preventDefault();
});
var toolbar = $('<div class="dm-popover"></div>');
if ( !$('.dm-popover').hasClass('in') ) {
setTimeout(function(){
toolbar.addClass('in');
},100);
$('body').prepend(toolbar);
}
toolbar.addClass('dm-link-frontend-control-top');
toolbar.css({
left: $(this).offset().left,
top: $(this).offset().top - toolbar.height() - 10
});
setTimeout(function(){
$('body').on('mouseup', function(e){
if($(e.target).closest(toolbar).length == 0){
$('body').unbind('click', arguments.callee);
toolbar.removeClass('in');
toolbar.remove();
}
});
}, 100);
e.stopPropagation();
});
You can try this
$(".element").on('mouseup', function(e){
$('[el-button]').click(function(e){
e.preventDefault();
});
if ( !$('.dm-popover').hasClass('in') )
{
var toolbar = $('<div class="dm-popover"></div>');
setTimeout(function(){
toolbar.addClass('in');
},100);
$('body').prepend(toolbar);
}
else
{
var toolbar = $('.dm-popover');
}
toolbar.addClass('dm-link-frontend-control-top');
toolbar.css({
left: $(this).offset().left,
top: $(this).offset().top - toolbar.height() - 10
});
setTimeout(function(){
$('body').on('mouseup', function(e){
if($(e.target).closest(toolbar).length == 0){
$('body').unbind('click', arguments.callee);
toolbar.removeClass('in');
toolbar.remove();
}
});
}, 100);
e.stopPropagation();
});
See the JSFiddle http://jsfiddle.net/wwL8fgr1/3/
The code responsible for removing the toolbar is here:
$('body').on('mouseup', function(e){
if($(e.target).closest(toolbar).length == 0){
$('body').unbind('click', arguments.callee);
toolbar.removeClass('in');
toolbar.remove();
}
});
Note this registers a mouseup handler on body. That's why you need to click on body to remove the toolbar. You can attach this handler to the second element, if that's what you expect.
EDIT
My guess is that you wanted to achieve something like in this fiddle. Note that is is suitable for 2 elements only, if you need more similar elements, you'd probably need to make a function to generate id's for you instead of storing them in data- attributes.
My opinion:
Your code seems overly complex - you're using timeouts, swapping css, mouseup instead of click, creating div elements on each click, preventing handler's propagation... Try to make it simpler by removing unnecessary stuff.
I've tried to create a jQuery effect using fancy box to contain my content and within that is a large image with thumbnails below. What I was trying to make happen was when the thumbnails are clicked then the large image updates (see RACE Twelve image as an example). This works fine but the problem is when I go to another fancy box on my website (SEE RACE ONE box) then that image has been updated to be whatever thumbnail was clicked last.
I thought this might be event bubbling but preventing default hasn't helped.
I'm very new to jQuery and know that this is something stupid that I'm doing.
Any advice would be greatly appreciated? Thank you :)
Live version of page: http://www.goodwood.co.uk/members-meeting/the-races.aspx
jsfiddle for jQuery: http://jsfiddle.net/greenhulk01/JXqzL/
(function ($) {
$(document).ready(function () {
$('.races-thumbnail').live("click", function (e) {
$('.races-main-image').hide();
$('.races-image-wrap').css('background-image', "url('http://www.goodwood.co.uk/siteelements/images/structural/loaders/ajax-loader.gif')");
var i = $('<img />').attr('src', this.href).load(function () {
$('.races-main-image').attr('src', i.attr('src'));
$('.races-image-wrap').css('background-image', 'none');
$('.races-main-image').fadeIn();
});
return false;
e.preventDefault();
});
$(".races-image-wrap img").toggle(function () { //fired the first time
$(".races-pop-info").show();
$(this).animate({
width: "259px",
height: "349px"
});
}, function () { // fired the second time
$(".races-pop-info").hide();
$('.races-main-image').animate({
width: "720px",
height: "970px"
});
});
$('#fancybox-overlay, #fancybox-close').live("click", function () {
$(".races-pop-info").show();
$(".races-main-image").animate({
width: "259px",
height: "349px"
});
});
});
})(jQuery);
$('.races-main-image') will select all elements with that class, even the ones which aren't currently visible.
You can select the closest '.races-main-image' to the clicked element as per the code below (when placed inside the click event handler)
$('.races-main-image', $(e.target).closest('.races-fancy-box'))
So your new code should look like:
$('.races-thumbnail').live("click", function (e) {
var racesmainimage = $('.races-main-image', $(e.target).closest('.races-fancy-box'));
var racesimagewrap = $('.races-image-wrap', $(e.target).closest('.races-fancy-box'));
racesmainimage.hide();
racesimagewrap.css('background-image', "url('http://www.goodwood.co.uk/siteelements/images/structural/loaders/ajax-loader.gif')");
var i = $('<img />').attr('src', this.href).load(function () {
racesmainimage.attr('src', i.attr('src'));
racesimagewrap.css('background-image', 'none');
racesmainimage.fadeIn();
});
return false;
});
I've also removed your 'e.preventDefault();' return false; includes that, and was preventing e.preventDefault() from being executed in any case.