0

I have multiple panels positioned offscreen with translateY property. Those panels have different heights. They are identified by this ids:

Panels:
  #panel-search // search form
  #panel-login // login form
  #panel-register // registration form
  #panel-navigation // navigation panel

The whole visible page itself is:

#page

And every panel is triggered by its own link:

Triggers:
  .btn-search // trigger search panel
  .btn-login // trigger login panel
  .btn-register // trigger registration panel
  .btn-nav // trigger navigation (this button shows only on mobile)

Also I use data-target attribute oon triggers which is equal to target panel's id.

What I need:

  1. Clicking any .btn-* will trigger appropriate panel. Panel slides down from top, page body slides simultaneously. Pretty simple to achieve. Done.
  2. When triggering any panel it should check if there's any panel open (this or any other). If it is, trigger that panel and page body off and only after that - show new panel (and move body again, to new position). That's where I'm stuck.

With the advice of @GauravBarar I've rewritten the code and now everything works except the chaining. When there's any open panel - I close it (and move page to top also) and after that open the requested panel. But it happens at the same time, simultaneously. And I need it to open new panel only after the original is closed. Tried adding setTimeout() (see commented section in the code) - the #page moves up/down with this timeout just fine, while the panel - don't.

Here's my code so far:

/**
 * Get real height of requested panel and prepare css transform property value.
 */
function getTransformProperty( panel ) {
    panelHeight = $('#'+panel).outerHeight();
    property = 'translateY(' + panelHeight + 'px)';
    return property;
}

/**
 * Move #page down by requested panel's height
 */
function setTransformProperty( property ) {
    $('#page').css({
        '-webkit-transform': property,
        '-moz-transform': property,
        '-ms-transform': property,
        '-o-transform': property,
        'transform': property
    });
    // Go to top (some triggers are in site footer, so we need this)
    window.scrollTo(0, 0);
}

// Trigger panels
$('[class*=trigger-]').click(function(){

    // Get target element to trigger
    var target = $(this).attr('data-target');

    // Check if current target is already opened and close it.
    if( $('#'+target).hasClass('is-visible-top') ) {

        $('#'+target).removeClass( 'is-visible-top' ); // move up requested panel
        setTransformProperty( 'translateY(0)' ); // move up page

        return false; // exit

    }

    // Check all panels in a loop. If any is opened - close it.
    $('[id*=panel-]').each(function(){

        // Get current panel's ID
        curPanelID = $(this).attr('id');

        if( $('#'+curPanelID).hasClass('is-visible-top') && curPanelID !== target ) {

            // A panel is opened.

            // Close it.
            $('#'+curPanelID).removeClass( 'is-visible-top' ); // move up currently open panel
            setTransformProperty( 'translateY(0)' ); // move up page

            // Open requested panel (HERE WE NEED A TIMEOUT)
            $('#'+target).addClass( 'is-visible-top' ); // move down requested panel
            setTransformProperty( getTransformProperty(target) ); // move down page by new height

            /* HERE'S TIMEOUT WHICH I TRIED BUT FAILED.
            setTimeout(function(){
                $('#'+target).addClass( 'is-visible-top' );
                setTransformProperty( getTransformProperty(target) ); 
            },300);
            */

            // exit each loop
            return false;

        } else {

            // No panel is opened. Just open requested without timeout.

            setTransformProperty( getTransformProperty(target) ); // move down page
            $('#'+target).addClass( 'is-visible-top' ); // move down requested panel

        }

    });

});

Any help much appreciated.

1
  • You could use a callback function. Link to similar problem Commented Aug 28, 2014 at 12:44

2 Answers 2

2

You can try using jQuery wildcards, like following:

$('[id*=panel-]').each(function(){
    //check if anyone is on or off
})
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the hint, never thought to use this selector. Reworking all the logics, using your idea makes everything shorter.
Thanx, everything is working fine except chaining. Tried setTimeout() to simulate this - not working properly. Can you please look what I'm missing? I've updated the code and commented every step.
The code is fine debug the code to check if the value of target is not getting lost and also check if the functions getTransformProperty, setTransformProperty are working properly. Or you can give me the complete code and I will check it for you.
1

For checking if a pannel is on or off you can use classes. Add a class like "PannelOn" to opend pannel when you open it. And after you close it remove this class.

Then when you open a pannel, before you open it check if any element exists with class "PannelOn" and close it (call your doTransform functions).

1 Comment

I already have and use a class is-visible-top. Trying to create that logic. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.