Search code examples
jqueryipaddropdown

Why is this happening only on ipad? jQuery reveal dropdown happening twice


I have a dropdown which is dynamic so the height should match the content and remain responsive.

It works on everything except ipads (tested on ipad 2 and 3), chrome and safari exhibit same behavior on it. I don't think its a double click issue.

Here is the jfiddle to see the issue:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>    
<style>
.toggle_content {   
/*visibility: hidden;*/
height: 0;
overflow: hidden;
-webkit-transition: height 350ms ease-in-out;
-moz-transition: height 350ms ease-in-out;
-o-transition: height 350ms ease-in-out;
transition: height 350ms ease-in-out;
}

.toggle_content.is-visible {
/*visibility:visible;*/
height: auto;
}
</style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script>
$.fn.showMe = function() {
//$(this).css("background-color","red");
var $el = $(this);

var getHeight = function () {        
    //$el.css({"visibility": 'visible'}); // Make it visible
    var height = $el.prop('scrollHeight') + 'px'; // Get it's height
    //$el.css({"visibility": ''}); //  Hide it again
    return height;
};

var height = getHeight(); // Get the natural height
$el.addClass('is-visible'); // Make the element visible
$el.css ({"height": height}); // Update the max-height

// Once the transition is complete, remove the inline max-height so the content can scale responsively
setTimeout(function () {
    $el.css ({"height": ''});
}, 350);
return false;
};

$.fn.hideMe = function() {
//$(this).css("background-color","red");
var $el = $(this);
    // Give the element a height to change from
$el.css ({"height": $el.prop('scrollHeight') + 'px'});

// Set the height back to 0
setTimeout(function () {
    $el.css ({"height": '0'});
}, 1);

// When the transition is complete, hide it
setTimeout(function () {
    $el.removeClass('is-visible');
}, 350);
return false;
};
</script>

</head>
<body>

<div class="toggle_dropdown">
<a class="byline" href="javascript:void(0);">Test dropdown</a>
<div class="toggle_content">
<div class="toggle_inner">
    <p>The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. </p>
</div>
</div>
</div>

<script>
// Show / hide dropdown
$(".byline").on("click touchend", function () {
//e.preventDefault();
//e.stopPropagation();
    var $dd = $(this).next('.toggle_content');
    if ($dd.hasClass("is-visible"))
        $dd.hideMe();            
    else
        ($dd.showMe());
        $(".toggle_content").not($dd).hideMe();
});
</script>

</body>
</html>

Any help appreciated.


Solution

  • Used the animate function for this issue in the end. It now works on all devices!

    https://jsfiddle.net/Bassquake/q2zo6e7b/

    I should note, the reason why Im using this kind of dropdown is because I couldnt use anything that used display:none or max-height as the dropdowns content was dynamic.

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>    
    <style>
    .toggle_content {   
    height: 0;
    overflow: hidden;
    background-color:#eee;
    }
    </style>
    
    <script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
    
    </head>
    
    <body>
    <div class="toggle_dropdown">
    <a class="byline" href="javascript:void(0);">Test dropdown</a>
    <div class="toggle_content">
    <div class="toggle_inner">
    <p>The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. </p>
    </div>
    </div>
    </div>
    
    <script>
    $('.byline').unbind('click touchend').click(function () {
        var $dd = $(this).next('.toggle_content');
    
        if ($dd.height() == 0) {
            $('.toggle_content').not($dd).animate({
                height: '0px'
            });
            $dd.animate({
                height: $dd.prop('scrollHeight') + 'px'
            }, {
                    complete: function () {
                        $dd.css({ "height": 'auto' });
                    }
                });
        } else {
            $dd.animate({
                height: '0px'
            });
        }
    
    });
    </script>
    
    </body>
    </html>