问题
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.
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:
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
回答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
回答2:
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.
Voilà, have a look
来源:https://stackoverflow.com/questions/51678230/how-to-force-shiftnav-to-lock-in-place-the-header-logo-on-menu-open