简体   繁体   中英

I have to click twice to get JQuery click function to fire

Here is the Fiddle . I have a problem; it seems almost random. Whenever I click a div to trigger an animation, I have to click twice to get the animation to fire. A little side note, in the fiddle, the animation isn't functional for some reason, so just assume it takes two clicks to animate each div; which is what I don't want.

HTML

<footer>
    <one id="one">
        <p unselectable="on"></p>
    </one>
    <two id="two">
        <p unselectable="on"></p>
    </two>
    <three-info>
    </three-info>
    <three id="three">
        <p unselectable="on"></p>
    </three>
</footer>

JavaScript

$(document).ready(function () {
    $('#three').click(function () {
        var clicks = $(this).data('clicks');
        if (clicks) {
            $("#three").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        } else {
            $("#three").animate({
                marginLeft: 0 + 'px'
            }, 800, 'linear');
        }
        $(this).data("clicks", !clicks);
        if ($("#two").css("marginLeft") == $(window).width() - 900 + 'px') {
            $("#two").animate({
                marginLeft: 0 + 'px'
            }, 100, 'linear');
            $("#three").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        }
        if ($("#one").css("marginLeft") == $(window).width() - 900 + 'px') {
            $("#one").animate({
                marginLeft: 0 + 'px'
            }, 100, 'linear');
            $("#three").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        }
    });
    $('#two').click(function () {
        var clicks = $(this).data('clicks');
        if (clicks) {
            $("#two").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        } else {
            $("#two").animate({
                marginLeft: 0 + 'px'
            }, 700, 'linear');
        }
        $(this).data("clicks", !clicks);
        if ($("#three").css("marginLeft") == $(window).width() - 900 + 'px') {
            $("#three").animate({
                marginLeft: 0 + 'px'
            }, 100, 'linear');
            $("#two").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        }
        if ($("#one").css("marginLeft") == $(window).width() - 900 + 'px') {
            $("#one").animate({
                marginLeft: 0 + 'px'
            }, 100, 'linear');
            $("#two").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        }
    });
    $('#one').click(function () {
        var clicks = $(this).data('clicks');
        if (clicks) {
            $("#one").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        } else {
            $("#one").animate({
                marginLeft: 0 + 'px'
            }, 700, 'linear');
        }
        $(this).data("clicks", !clicks);
        if ($("#two").css("marginLeft") == $(window).width() - 900 + 'px') {
            $("#two").animate({
                marginLeft: 0 + 'px'
            }, 100, 'linear');
            $("#one").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        }
        if ($("#three").css("marginLeft") == $(window).width() - 900 + 'px') {
            $("#three").animate({
                marginLeft: 0 + 'px'
            }, 100, 'linear');
            $("#one").animate({
                marginLeft: $(window).width() - 900 + 'px'
            }, 745, 'linear');
        }
    });
});

CSS

footer {
    margin: 0;
    padding: 0;
    float: left;
    width: 100%;
    height: 115px;
    background-color: #4a4a4a;
    overflow: visible !important;
    -webkit-user-select: none; /* Chrome/Safari */        
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */

/* Rules below not implemented in browsers yet */
-o-user-select: none;
user-select: none;
}
one {
    margin: 0;
    padding: 0;
    float: left;
    width: 200px;
    background-color: pink;
    height: 115px;
    margin-left: 0px;
    display: block;
}
one,two,three {
    text-align: center;
    color: white;
    font-family: "Raleway", Arial, Helvetica, Trebuchet MS, Tahoma, sans-serif;
    font-weight: bold;
    font-size: 16px;
    line-height: 115px;
}
one:hover {
    background: black;
    margin: 0;
    padding: 0;
    height: 115px;
    float: left;
    transition: all 0.3s ease-out; 
    cursor: pointer;
}
two:hover {
    background: black;
    margin: 0;
    padding: 0;
    height: 115px;
    float: left; 
    transition: all 0.3s ease-out;
    cursor: pointer;
}
three:hover {
    background: black;
    margin: 0;
    padding: 0;
    height: 115px;
    float: left; 
    transition: all 0.3s ease-out;
    cursor: pointer;
}
two {
    margin: 0;
    padding: 0;
    float: left;
    width: 200px;
    background-color: gray;
    height: 115px;
    margin-left: 0px;
    display: block;
}
three {
    margin: 0;
    padding: 0;
    float: left;
    width: 200px;
    background-color: black;
    height: 115px;
    margin-left: 0px;
    display: block;
}

Your code requires you to click twice because on the first click your clicks data hasn't been set yet so your else clause of your if statement happens first

//"clicks" will be undefined the first time through
var clicks = $(this).data('clicks'); 
if (clicks) {
   $("#two").animate({marginLeft: $(window).width()-900 +'px'}, 745, 'linear');
} else {
   //so this part gets executed first
   $("#two").animate({marginLeft: 0 +'px'}, 700, 'linear');
}

You can either set a data-* attribute or use .data() to set it

$("#three").data('clicks',true);
$("#two").data('clicks',true);
$("#one").data('clicks',true);

Or

<three id="three" data-clicks="1">

Fiddle

The problem is when the element is first clicked the value of data-clicks attribute is undefined . You can set this value in HTML by adding data-clicks="true" or you can also set the value in Javascript as

$('#one, #two, #three').data('clicks', true);

I've also optimised your code to make it dry.

Demo

 $(document).ready(function() { // To animate the other elements than the clicked one function animateOthers(clickedElement, otherElement) { otherElement.animate({ marginLeft: 0 + 'px' }, 100, 'linear'); clickedElement.animate({ marginLeft: $(window).width() - 900 + 'px' }, 745, 'linear'); } // To animate the element that is clicked function animate(clicks, first, otherElements) { var leftMargin = ($(window).width() - 900) + 'px'; var left = '0px', duration = 800; if (clicks) { // Update the marginLeft and duration to animate left = leftMargin; duration = 745; } // Animate the clicked element first.animate({ marginLeft: left }, duration, 'linear'); // For other elements otherElements.forEach(function(v) { if ($('#' + v).css('marginLeft') == leftMargin) { animateOthers(first, $('#' + v)); } }); // Update the data-clicks value by negating it first.data("clicks", !clicks); } // Array of all the elements var elements = ['one', 'two', 'three']; // Bind click event on the elements on the array $('#' + elements.join(',#')).on('click', function() { var clicks = $(this).data('clicks'); var clickedElement = $(this).attr('id'), otherElements = elements.slice(); otherElements.splice(elements.indexOf(clickedElement), 1); // otherElements is the array of the elements other than the clicked animate(clicks, $(this), otherElements); }); }); 
 footer { margin: 0; padding: 0; float: left; width: 100%; height: 115px; background-color: #4a4a4a; overflow: visible !important; -webkit-user-select: none; /* Chrome/Safari */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* IE10+ */ /* Rules below not implemented in browsers yet */ -o-user-select: none; user-select: none; } one { margin: 0; padding: 0; float: left; width: 200px; background-color: pink; height: 115px; margin-left: 0px; display: block; } one, two, three { text-align: center; color: white; font-family: "Raleway", Arial, Helvetica, Trebuchet MS, Tahoma, sans-serif; font-weight: bold; font-size: 16px; line-height: 115px; } one:hover { background: black; margin: 0; padding: 0; height: 115px; float: left; transition: all 0.3s ease-out; cursor: pointer; } two:hover { background: black; margin: 0; padding: 0; height: 115px; float: left; transition: all 0.3s ease-out; cursor: pointer; } three:hover { background: black; margin: 0; padding: 0; height: 115px; float: left; transition: all 0.3s ease-out; cursor: pointer; } two { margin: 0; padding: 0; float: left; width: 200px; background-color: gray; height: 115px; margin-left: 0px; display: block; } three { margin: 0; padding: 0; float: left; width: 200px; background-color: black; height: 115px; margin-left: 0px; display: block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script> <footer> <one id="one" data-clicks="true"> <p unselectable="on"></p> </one> <two id="two" data-clicks="true"> <p unselectable="on"></p> </two> <three-info></three-info> <three id="three" data-clicks="true"> <p unselectable="on"></p> </three> </footer> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM