How to force ShiftNav to Lock in place the Header (Logo) on menu-open
Asked Answered
M

2

1

I am trying to make the ShiftNav menu plugin to apply Lock Scroll - aka lock_body in source code - on a new theme, which should make the-shifted-to-the right-by-the-opened-menu-content locked on y-scroll - obviously, (tested on previous theme). This option will work if the Shift Body will be enabled, which I did.

enter image description here enter image description here

In these conditions the Lock Scroll it doesn't work. I've tried to fix the header and other elements in position using position: fixed !important; but as soon as the left menu will open, the header logo, etc, will go up at scroll.

The theme and the plugin have plenty of js, css, code; I really can't reproduce this into a fiddle, I have no knowledge to do this, sorry to being off MCVE, but I can provide a live link, and the sequences that should produce the lock scroll at menu-open.

In settings.config.php it looks like this (the bottom part)

function shiftnav_get_settings_fields(){

$prefix = SHIFTNAV_PREFIX;


$main_assigned = '';
if(!has_nav_menu('shiftnav')){
    $main_assigned = 'No Menu Assigned';
}
else{
    $menus = get_nav_menu_locations();
    $menu_title = wp_get_nav_menu_object($menus['shiftnav'])->name;
    $main_assigned = $menu_title;
}

$main_assigned = '<span class="shiftnav-main-assigned">'.$main_assigned.'</span>  <p class="shiftnav-desc-understated">The menu assigned to the <strong>ShiftNav [Main]</strong> theme location will be displayed.  <a href="'.admin_url( 'nav-menus.php?action=locations' ).'">Assign a menu</a></p>';

$fields = array(


    $prefix.'shiftnav-main' => array(

        array(
            'name'  => 'menu_assignment',
            'label' => __( 'Assigned Menu' , 'shiftnav' ),
            'desc'  => $main_assigned,
            'type'  => 'html',

        ),

        ....

$fields = apply_filters( 'shiftnav_settings_panel_fields' , $fields );

$fields[$prefix.'general'] = array(

    array(
        'name'      => 'lock_body',
        'label'     => __( 'Lock Scroll', 'shiftnav' ),
        'desc'      => __( 'Lock both vertical and horizontal scrolling on site content when menu is active.  No effect if <strong>Shift Body</strong> is disabled.', 'shiftnav' ),
        'type'      => 'checkbox',
        'default'   => 'on'
    ),
);


return $fields;

In shiftnav.js file we have:

        /* Initalizers */

    initializeShiftNav: function(){

        var $body = $('body'),
            plugin = this;

        //Only enable the site once
        if( !$body.hasClass( 'shiftnav-enabled' ) ){

            $body.addClass( 'shiftnav-enabled' );
            if( shiftnav_data.lock_body == 'on' ) $body.addClass( 'shiftnav-lock' );
            if( shiftnav_data.lock_body_x == 'on' ) $body.addClass( 'shiftnav-lock-x' );

            if( shiftnav_data.shift_body != 'off' ){
                if( shiftnav_data.shift_body_wrapper != '' ){
                    $( shiftnav_data.shift_body_wrapper ).addClass( 'shiftnav-wrap' );
                }
                else{
                    $body.wrapInner( '<div class="shiftnav-wrap"></div>' ); //unique
                    $( 'video[autoplay]' ).each( function(){
                        $(this).get(0).play();
                    });
                }
            }
            else $body.addClass( 'shiftnav-disable-shift-body' );

            //Move elements outside of shifter
            $( '#shiftnav-toggle-main, #wpadminbar, .shiftnav-fixed-left, .shiftnav-fixed-right' ).appendTo( 'body' );

            var $wrap = $( '.shiftnav-wrap' );

            //Pad top
            var toggleHeight = $( '#shiftnav-toggle-main' ).outerHeight();
            $wrap.css( 'padding-top' , toggleHeight );
            if( shiftnav_data.shift_body == 'off' ) $body.css( 'padding-top' , toggleHeight );

            //Setup non-transform
            //Some browsers provide false positives for feature detection, so we have to do browser detection as well, sadly
            var fpos = false;   //falsePositive - 
            var ua = navigator.userAgent.toLowerCase();

            //Many mobile Android browsers are dumb
            if( /android/.test( ua ) ){
                fpos = true; //we're going to whitelist mobile Android browsers, so assume false positive on Android

                //always ignore old androids
                if( /android [1-3]/.test( ua ) ) fpos = true;
                //Chrome on 4+ is good
                else if( /chrome/.test( ua ) ) fpos = false;
                //Firefox on 4+ is good
                else if( /firefox/.test( ua ) ) fpos = false;

                //always allow Chrome
                //else if( /chrome/.test( ua ) ) fpos = false;
                //Android 4.4+ is okay
                //else if( /android 4.[4-9]/.test( ua ) ) fpos = false;
                //else fpos = true;
            }


            if( !shift_supports( 'transform' ) || fpos || plugin.settings.disable_transforms ){
                $body.addClass( 'shiftnav-no-transforms' );
            }


            //Setup swipe open on MAIN SHIFTNAV only
            if( shiftnav_data.swipe_open == 'on' ){
                var wrap_start_y = 0,
                    wrap_start_x = 0,
                    wrap_cur_y = 0,
                    wrap_cur_x = 0,
                    viewport_width = $( window ).width();


                if( shiftnav_data.shift_body == 'off' ) $wrap = $( 'body' );

                $wrap.on( 'touchstart' , function( e ){
                    if( plugin.settings.breakpoint && $( window ).width() > plugin.settings.breakpoint ) return;
                    wrap_start_y = e.originalEvent.changedTouches[0].pageY;
                    wrap_start_x = e.originalEvent.changedTouches[0].pageX;
                    //console.log( "START: " + wrap_start_x );
                });

                //Left edge activate on swipe from left
                if( $( '#shiftnav-main' ).hasClass( 'shiftnav-left-edge' ) ){
                    $wrap.on( 'touchmove' , function( e ){
                        wrap_cur_x = e.originalEvent.changedTouches[0].pageX;
                        //console.log( wrap_cur_x );

                        //if close to left edge 
                        if( wrap_start_x < plugin.settings.swipe_edge_proximity ){
                            e.preventDefault();

                            //if swipe more than 150
                            if( wrap_cur_x - wrap_start_x > plugin.settings.swipe_tolerance_x ){
                                wrap_cur_y = e.originalEvent.changedTouches[0].pageY;
                                if( Math.abs( wrap_cur_y - wrap_start_y ) < plugin.settings.swipe_tolerance_y ){
                                    plugin.openShiftNav( 'swipe right' );
                                    e.stopPropagation();
                                }
                            }
                        }
                    });
                }
                //Right edge activate on swipe from right
                else{
                    $wrap.on( 'touchmove' , function( e ){
                        wrap_cur_x = e.originalEvent.changedTouches[0].pageX;

                        //if we start from the edge, tell android we've got this covered
                        if( wrap_start_x > ( viewport_width - plugin.settings.swipe_edge_proximity ) ){
                            e.preventDefault();

                            //if swipe more than 150, open panel
                            if( ( wrap_start_x - wrap_cur_x > plugin.settings.swipe_tolerance_x ) ){
                                wrap_cur_y = e.originalEvent.changedTouches[0].pageY;
                                if( Math.abs( wrap_cur_y - wrap_start_y ) < plugin.settings.swipe_tolerance_y ){
                                    plugin.openShiftNav( 'swipe left' );
                                    e.stopPropagation();
                                }
                            }
                        }


                    });
                }
            }

            //Handle searchbar toggle
            $( '.shiftnav-searchbar-toggle' ).on( this.toggleevent , function( e ){
                e.stopPropagation();
                e.preventDefault();

                var $drop = $( this ).next( '.shiftnav-searchbar-drop' );

                //Close
                if( $drop.hasClass( 'shiftnav-searchbar-drop-open' ) ){
                    $drop.removeClass( 'shiftnav-searchbar-drop-open' );
                    $( 'body' ).off( 'click.shiftnav-searchbar-drop' );
                }
                //Open
                else{
                    $drop.addClass( 'shiftnav-searchbar-drop-open' );
                    $drop.find( '.shiftnav-search-input' ).focus();

                    //Close on click-off - can't do this immediately because IE is so damn dumb
                    setTimeout( function(){
                        $( 'body' ).on( 'click.shiftnav-searchbar-drop' , function( e ){
                            $( '.shiftnav-searchbar-drop' ).removeClass( 'shiftnav-searchbar-drop-open' );
                            $( 'body' ).off( 'click.shiftnav-searchbar-drop' );
                        });
                    }, 100);
                }
            });
            $( '.shiftnav-searchbar-drop' ).on( this.toggleevent , function( e ){
                e.stopPropagation();
            });
            $( '.shiftnav-searchbar-drop .shiftnav-search-input').on( 'blur' , function( e ){
                if( $( this ).val() == '' && !toggle_clicked ){
                    $( this ).parents( '.shiftnav-searchbar-drop' ).removeClass( 'shiftnav-searchbar-drop-open' );
                }
            });
            var toggle_clicked;
            $( '.shiftnav-searchbar-toggle' ).on( 'mousedown' , function( e ){
                toggle_clicked = true;
            });
            $( '.shiftnav-searchbar-toggle' ).on( 'mouseup' , function( e ){
                toggle_clicked = false;
            });


        }

        this.$shiftnav.appendTo( 'body' );

        if( this.$shiftnav.hasClass( 'shiftnav-right-edge' ) ){
            this.edge = 'right';
        }
        else this.edge = 'left';

        this.openclass = 'shiftnav-open shiftnav-open-' + this.edge;

        //Set retractor heights
        this.$shiftnav.find( '.shiftnav-submenu-activation' ).each( function(){
            var length = $( this ).outerHeight();
            $( this ).css( { 'height' : length , 'width' : length } );

            //$( this ).css( 'height' , $( this ).parent( '.menu-item' ).height() );
        });



        //Current open
        if( plugin.settings.open_current ){
            $( '.shiftnav .shiftnav-sub-accordion.current-menu-item, .shiftnav .shiftnav-sub-accordion.current-menu-ancestor' ).addClass( 'shiftnav-active' );
        }

    },

In page index.html also we have "lock_body":"on" here:

    /* <![CDATA[ */
var shiftnav_data = {"shift_body":"on","shift_body_wrapper":".edge-wrapper","lock_body":"on","lock_body_x":"off","swipe_close":"off","swipe_open":"off","swipe_tolerance_x":"150","swipe_tolerance_y":"60","swipe_edge_proximity":"80","open_current":"off","collapse_accordions":"off","scroll_panel":"off","breakpoint":"","touch_off_close":"off","scroll_offset":"100","disable_transforms":"off"};
/* ]]> */

The Chrome console looks like this:

enter image description here

At this point I am interested to know if there is a possibility to force the ShiftNav to apply the Lock Scroll on this new theme; it will be great to have it applied ONLY to header and his elements (logo, etc) in other words,

It will be great to have the header fixed like the burger button at scrollTop when the menu is expanded to the right.

Website testpage

enter image description here

Microphyte answered 3/8, 2018 at 18:27 Comment(4)
For best results - read on to how to create a minimal reproducible exampleFrilling
I understand, but if it is so hard to make a MCVE then it will be even harder for others to help you without being able to quickly look at a piece of code and see what is broken.Frilling
If you really can't provide a mcve, it's good to explain why, as you did in your comment. But do it in the question :) Seems someone already found an answer bellow though.Frilling
@Frilling I've found the issue, is related to the Lock Scroll aka lock_body option of the plugin that doesn't apply, tested on other theme.Microphyte
M
0

I've found a nice workaround that will ignore all the -webkit-transform, transform styling declarations and so on. Someone said : ... you can’t have a fixed element inside an element that has CSS transforms applied to it; Fixed position elements will act as position:absolute within a transformed context. This is actually part of the CSS spec.

Well, in this particular case, talking about ShiftNav and a custom theme, The good news is that

  • Yes you can, as long as you look at the picture having a step backward in order to see the whole picture.

The solution is to remove the logo from the header (or other elements as long as there is no facy stuff going on up there) and to put these elements into the Toggle Bar > Toggle Content Field inside the ShiftNav Settings. This will allow you to use without restrictions the Shift Body option, you will have a "fake header" fixed, the content is scrollable even if the main wrapp is shifted by the push-side menu, everything is nice, thanks to this plugin.

enter image description here

Voilà, have a look

enter image description here

Microphyte answered 4/8, 2018 at 17:43 Comment(1)
I just tried testing this on my own menu, and noticed it doesn't work anymore, or maybe I hadn't tested it further. But I found that under ShiftNav's General Settings, there should be an option for CSS Tweaks. All I did was add CSS for the classes shiftnav-menu-image and shiftnav-nav. For the menu image, I gave it a fixed position, a z-index of 99 to put it on top of everything, and a background color corresponding to the one being used. The nav simply has a margin-top equal to the menu image container's height.Parrakeet
K
1

This is due to your -webkit-transform and transform styling declarations for the containing
<div class="edge-wrapper shiftnav-wrap">. transform creates a new local coordinate system so the logo is fixed to that coordinate system rather than the body. see these posts: 1 2 3

Kath answered 3/8, 2018 at 18:56 Comment(4)
not so sure because I saw a workaround in pretty much the same scenario using ShiftNav; I guess that was related to applying overflow-y: hidden on the right scrollbar but not so sure how to do it / test this. In Chrome console I can't select the scrollbar in order to investigate/find the element and to apply overflow-y: hidden ; anyway upvote for your effort, thank you!Microphyte
Of course the overflow-y : hidded applied on scrollbar was meant to have the effect only at menu open.Microphyte
Hmm you could maybe set the height of the <div class="edge-wrapper shiftnav-wrap"> to 100vh and then create some JS/JQuery to move the everything other than the top part manually with using a scroll listener.Kath
I'll ask the ShiftNav Creator too. Thanks anyway :)Microphyte
M
0

I've found a nice workaround that will ignore all the -webkit-transform, transform styling declarations and so on. Someone said : ... you can’t have a fixed element inside an element that has CSS transforms applied to it; Fixed position elements will act as position:absolute within a transformed context. This is actually part of the CSS spec.

Well, in this particular case, talking about ShiftNav and a custom theme, The good news is that

  • Yes you can, as long as you look at the picture having a step backward in order to see the whole picture.

The solution is to remove the logo from the header (or other elements as long as there is no facy stuff going on up there) and to put these elements into the Toggle Bar > Toggle Content Field inside the ShiftNav Settings. This will allow you to use without restrictions the Shift Body option, you will have a "fake header" fixed, the content is scrollable even if the main wrapp is shifted by the push-side menu, everything is nice, thanks to this plugin.

enter image description here

Voilà, have a look

enter image description here

Microphyte answered 4/8, 2018 at 17:43 Comment(1)
I just tried testing this on my own menu, and noticed it doesn't work anymore, or maybe I hadn't tested it further. But I found that under ShiftNav's General Settings, there should be an option for CSS Tweaks. All I did was add CSS for the classes shiftnav-menu-image and shiftnav-nav. For the menu image, I gave it a fixed position, a z-index of 99 to put it on top of everything, and a background color corresponding to the one being used. The nav simply has a margin-top equal to the menu image container's height.Parrakeet

© 2022 - 2024 — McMap. All rights reserved.