如何在菜单打开时强制ShiftNav将页眉(徽标)锁定在适当的位置

时间:2018-08-03 18:27:39

标签: css wordpress css-position custom-wordpress-pages

我正在尝试制作ShiftNav菜单插件,以将Lock Scroll(也称为lock_body)应用到源代码中的新主题上,这应该使右移-由打开的菜单内容锁定在y滚动上-显然,(在以前的主题上进行了测试)。如果我启用了Shift档,此选项将起作用。

enter image description here enter image description here

在这些情况下,锁定滚动条不起作用。我尝试使用headerposition: fixed !important;和其他元素固定在适当的位置,但是一旦打开左侧菜单,header logo等就会上升在滚动。

主题和插件包含大量jscss代码。我真的不能将它复制到小提琴中,我不知道这样做,很抱歉退出MCVE,但是我可以提供实时链接,并且应该在菜单打开时提供锁定滚动的顺序。

settings.config.php中,它看起来像这样(底部)

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;

shiftnav.js文件中,我们有:

        /* 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' );
        }

    },

在页面index.html中,我们还有"lock_body":"on"

    /* <![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"};
/* ]]> */

Chrome控制台看起来像这样:

enter image description here

这时我很想知道是否有可能强迫ShiftNav在这个新主题上应用Lock Scroll;最好仅将其应用于标头及其元素(徽标等),即

将菜单扩展到右侧时,像scrollTop上的“汉堡”按钮一样固定标题是非常好的。

Website testpage

enter image description here

2 个答案:

答案 0 :(得分:1)

这是由于-webkit-transform和包含的内容的转换样式声明
<div class="edge-wrapper shiftnav-wrap">。变换创建了一个新的局部坐标系,因此徽标固定在该坐标系上,而不是主体上。 请参阅以下帖子:1 2 3

答案 1 :(得分:0)

我找到了一个不错的解决方法,它将忽略所有-webkit-transform,转换样式声明等。有人说:... 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.

在这种情况下,谈论ShiftNav和自定义主题,好消息是

  • ,只要您看向后退一步即可看到整个图片。

解决方案是从header(或其他元素,只要上面没有花哨的东西)上删除徽标,并将这些元素放入ShiftNav中的“切换栏”>“切换内容字段”设定这将允许您不受限制地使用Shift Body选项,将固定为“ fake header”,即使主wrapp被推侧菜单移动,内容仍可滚动,所有内容很好,感谢这个插件。

enter image description here

Voilà, have a look

enter image description here