简体   繁体   English

如何使用响应式菜单防止正文滚动

[英]How to prevent body from scrolling with Responsive menu

I am trying to properly implement the Responsive Menu plugin into a wordpress theme.我正在尝试将响应式菜单插件正确实施到 wordpress 主题中。 The issue appears when the push-side menu is open, which cause body to move at vertical scroll.当推送侧菜单打开时会出现此问题,这会导致body以垂直滚动方式移动。

At this moment, there is a solution for this template page that is working amazing and I'm happy with the result.目前,这个模板页面有一个解决方案,效果非常好,我对结果很满意。

The question: Taking in consideration Outsource WordPress 's answer, which fix the above specified page, is there any possibility to tweak the below code in order to be usable in more general way in other template pages as well for example here like already is running here ?问题:考虑到Outsource WordPress的答案,它修复了上面指定的页面,是否有可能调整下面的代码以便在其他模板页面中以更通用的方式使用,例如这里就像已经在运行在这里

I suppose that .edge-ils-item-link and .edge-ils-content-table are variables but I have no idea how to approach and adapt this, I've made some tests replacing these elements but with no positive results, maybe it's not that simple, it's more than that.我想.edge-ils-item-link.edge-ils-content-table是变量,但我不知道如何处理和调整它,我已经做了一些测试来替换这些元素但没有积极的结果,也许这不是那么简单,还不止于此。 I also know that edge-wrapper , edge-wrapper-inner , wpb_wrapper are found in every pages, these could be the common elements that could change the solution making it available for every page.我也知道edge-wrapperedge-wrapper-innerwpb_wrapper在每个页面中都可以找到,这些可能是可以更改解决方案使其可用于每个页面的常见元素。

Also it will be great to be jQuery ready according to the latest version (at this point I am using jQuery migrate 1.4.1 and an old version of Wordpress in order to be functional at least on the page designed for).根据最新版本准备好 jQuery 也很棒(此时我正在使用 jQuery 迁移 1.4.1 和旧版本的 Wordpress 以便至少在页面上设计功能)。

.scroll-lock{position:fixed;important;}

$(document).ready(function() {
    var windowTop = 0;
    var menuOpen = 0;
    var offsetContainerList = 0;

    $('#responsive-menu-pro-button').click(function() {
        var offsetScrollList = $('.edge-ils-item-link:first').offset().top; 

        if ($('html').hasClass('scroll-lock')) {
            $('#responsive-menu-pro-container').one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",
              function(event) {
                  if (menuOpen==0) {
                      menuOpen = 1;
                      $('html').removeClass('scroll-lock');  
                      $('.edge-ils-content-table').css('top', eval(offsetContainerList)-40+'px'); //change image container top position
                      $('html').scrollTop(windowTop); //scroll to original position
                  }
                  else {   
                      menuOpen = 0;             
                  }
            });
        }
        else {                
            windowTop = $(window).scrollTop();
            offsetContainerList = $('.edge-ils-content-table').offset().top;  
            $('html').addClass('scroll-lock');      
            $('.edge-ils-content-table').css('top', -offsetScrollList + 'px'); //change image container top position
        }      
    }); 
}); 

Video with the issue, if this helps here .有问题的视频,如果这有帮助话。

I noticed that the class of scroll-lock is not getting added to the html element in your page called "scroll-lock", but it is added on the "ilinks-push" page.我注意到scroll-lock的 class 没有被添加到您页面中名为“滚动锁”的 html 元素中,但它被添加到“ilinks-push”页面上。 So the if checking if the html has this class will never become true on your sub pages.因此,如果检查 html 是否具有此 class 将永远不会在您的子页面上变为 true。 I rewrote the code so it will look for the inteded class called responsive-menu-pro-open .我重写了代码,因此它会查找名为responsive-menu-pro-open的内置 class 。

But moreover to make it work for your subpages, you need to understand the logic in the provided code.但此外,要使其适用于您的子页面,您需要了解所提供代码中的逻辑。 I did some changes and added comments to make it more clear:我做了一些更改并添加了评论以使其更加清晰:

$(document).ready(function() {
    var windowTop = 0;

    $('#responsive-menu-pro-button').click(function() {

        /* check if there is a ils item link */
        if ( $('.edge-ils-item-link')[0] ) {
            /* save space above the element to variable */
            var offsetScrollList = $('.edge-ils-item-link:first').offset().top;
        }

        /****** Menu gets opened ******/

        if ($('html').hasClass('responsive-menu-pro-open')) {

            /* scroll to top of page */
            windowTop = $(window).scrollTop(); 
            /* add the scroll-lock class */
            $('html').addClass('scroll-lock');
            
            /* check if there is a ils item link */
            if ( $('.edge-ils-item-link')[0] ) {
                /* add the saved space again to look like the same scroll position we started with */      
                $('.edge-ils-content-table').css('top', -offsetScrollList + 'px'); 
            }
            
        }

        /****** Menu gets closed ******/

        else { 
            $('html').removeClass('scroll-lock');

            /* check if there is a ils item link */
            if ( $('.edge-ils-item-link')[0] ) {
                /* again use the saved space to make it look like the start position */
                $('.edge-ils-content-table').css('top', -offsetScrollList +'px');
            }

            $('html').scrollTop(windowTop);
        }

    }); 
}); 

You see the parts where there is check if there is a ils item link written?您看到有check if there is a ils item link

This will be the parts that are different on your subpages.这将是您子页面上不同的部分。

With using .offset().top we are getting the space above the elements.通过使用.offset().top我们得到了元素上方的空间。 This will only work, if there are actually elements with the class of .edge-ils-item-link which is why I put the code inside of the if clauses.这只有在实际存在具有.edge-ils-item-link的 class 的元素时才有效,这就是我将代码放在 if 子句中的原因。

In the code you are using the spaces above to position the elements in the right place, so it will look like the scroll is blocked.在代码中,您使用上面的空格将 position 元素放在正确的位置,因此看起来滚动被阻止了。

To target the right elements, we need the class of it.要定位正确的元素,我们需要它的 class。

So you have to make sure, that every page uses the same class around the content area.因此,您必须确保每个页面在内容区域周围使用相同的 class。 This way you are able to target them on every page without additional if clauses in the javascript.这样,您无需在 javascript 中添加额外的 if 子句,就可以在每个页面上定位它们。

Alternatively you could right a bounch of if clauses and check the elements in your pages.或者,您可以纠正一堆 if 子句并检查页面中的元素。 In your page called "scroll-lock" it might be the element of info-field you can use to set the spaces.在您的名为“滚动锁定”的页面中,它可能是info-field的元素,您可以使用它来设置空格。 But in this page you have the content placed with fixed position (don't know why, are you using some fancy block builder or something? markup looks aweful), so this causes problems, when adding your class of scroll-lock with the position: fixed;但是在此页面中,您将内容放置在固定的 position 中(不知道为什么,您是在使用一些花哨的块生成器还是什么?标记看起来很棒),所以当您使用position: fixed;添加 class 的scroll-lock时,这会导致问题position: fixed; . .

I think you need to adjust the content of your other pages, so this problem can be solved for you.我认为您需要调整其他页面的内容,以便可以为您解决这个问题。 It will not be a good practice to adjust the javascript for every of your subpage with different content elements.为每个具有不同内容元素的子页面调整 javascript 不是一个好习惯。 Try to make every subpage in two columns (using flexbox).尝试将每个子页面分成两列(使用 flexbox)。 Maybe the left one will always be fixed and the right one is static and therefore scrollable.也许左边永远是固定的,右边是 static,因此可以滚动。 We don't know this with the information given in your question.根据您问题中提供的信息,我们不知道这一点。

Ok, first lets talk about the issue:好的,首先让我们谈谈这个问题:

The plugin is setting transform: translateX(800px);该插件正在设置transform: translateX(800px); on your main div, but, transform remove the position: fixed from all of its children, so all your inner divs that have position fixed, are basically moved to be position relative so they are basically moved to the top.在您的主 div 上,但是,将position: fixed从其所有子项中删除,因此您所有固定 position 的内部 div 基本上都移动到 position 相对位置,所以它们基本上移动到顶部

The Too Complex Solution:太复杂的解决方案:

You can of course play with scrolling the user to the top, saving what position he was, and do a real complex solution to workaround this issue, BUT, all of this for a left menu?您当然可以将用户滚动到顶部,保存他原来的 position,然后做一个真正复杂的解决方案来解决这个问题,但是,所有这些都用于左侧菜单? it seems to be so much work for a simple fixed div that push other fixed div to the right.对于一个简单的固定 div 来说,将其他固定 div 推到右侧似乎需要做很多工作。

The Easy Solution: Why wouldn't we just omit the transform, and use margin-left?简单的解决方案:我们为什么不直接省略变换,而使用左边距?

<style>

html.responsive-menu-pro-open {
  overflow-y: hidden !important;
  padding-right: 9px;
} 

#responsive-menu-pro-container {
  position: fixed !important;
}

#responsive-menu-pro-container {
  position: fixed !important;
  transform: none !important;
  margin-left: -800px;

  transition: 2.6s ease; 
  transition-timing-function: cubic-bezier(0.96, 0, 0.13, 1); 
  transition-property: margin-left; 
}

#responsive-menu-pro-button {
  transform: none !important;
  transition: 2.6s ease !important; 
  transition-timing-function: cubic-bezier(0.96, 0, 0.13, 1) !important; 
  transition-property: margin-left !important;
}

.responsive-menu-pro-open #responsive-menu-pro-button {
   margin-left: 800px;
}

#responsive-menu-pro-header {
  transform: none !important;
  transition: 2.6s ease; 
  transition-timing-function: cubic-bezier(0.96, 0, 0.13, 1); 
  transition-property: margin-left; 
}

.responsive-menu-pro-open #responsive-menu-pro-header {
  margin-left: 800px;
}

.responsive-menu-pro-open .edge-wrapper {
  transform: none !important;
}

.responsive-menu-pro-open .edge-wrapper .edge-wrapper-inner {
  margin-left: 800px;
}

.edge-wrapper .edge-wrapper-inner {
  transition: 2.6s ease; 
  transition-timing-function: cubic-bezier(0.96, 0, 0.13, 1); 
  transition-property: margin-left; 
}

.responsive-menu-pro-open .edge-content .edge-ps-navigation {
  margin-left: 800px;
}

.edge-content .edge-ps-navigation {
  transition: 2.6s ease; 
  transition-timing-function: cubic-bezier(0.96, 0, 0.13, 1); 
  transition-property: margin-left; 
}

.responsive-menu-pro-open #responsive-menu-pro-container {
  margin-left: 0;
  transition: 2.6s ease; 
  transition-timing-function: cubic-bezier(0.96, 0, 0.13, 1); 
  transition-property: margin-left; 
}

.responsive-menu-pro-open .edge-back-to-top-text {
  display: none;
}

</style>

By adding the snippet above, you mimic the functionality you want without transform using margin-left.通过添加上面的代码片段,您可以模拟您想要的功能,而无需使用 margin-left 进行转换。

Notes - because of your page layout (its a bit of a mess, a lot of position fixed elements, inside other position fixed elements), you need to set margin-left to different elements, changing the page layout would make it much easier to apply this, or even use the native transform functionality of the plugin.注意- 由于您的页面布局(它有点乱,很多 position 固定元素,在其他 position 固定元素内),您需要将 margin-left 设置为不同的元素,更改页面布局会更容易应用它,甚至使用插件的本机转换功能。

This solution might only work on the example page you gave us, you will need to set marign-left on the correct elements on your other pages, but again, if you layout all of your pages into a single wrapper div, that will hold the functionality, and remove other fixed elements, you will be able to create a single code snippet that will work on pages.此解决方案可能仅适用于您提供给我们的示例页面,您需要在其他页面上的正确元素上设置 marign-left,但同样,如果您将所有页面布局到单个包装器 div 中,它将保存功能,并删除其他固定元素,您将能够创建一个适用于页面的代码片段。

Bottom line - the plugin have issues because of your page layout, contacting the plugin developers might give you a better answer, and they might look into your specific theme and bring a much better solution.底线- 由于您的页面布局,插件存在问题,联系插件开发人员可能会给您一个更好的答案,他们可能会研究您的特定主题并带来更好的解决方案。 Without seeing your code this is the best work-around I could find without trying to play with scrolls.在没有看到您的代码的情况下,这是我能找到的最好的解决方法,而无需尝试使用滚动。

Add min-height: 100vh;添加min-height: 100vh; to the body tag.到正文标签。 It will show verticle scroll only if the content exceeds the viewport height.只有当内容超过视口高度时,它才会显示垂直滚动。

Currently, the document height in your pages is locked to the total height of relatively positioned children.目前,您页面中的文档高度锁定为相对定位的子项的总高度。 Refer below screenshots.请参阅下面的屏幕截图。 在此处输入图像描述

在此处输入图像描述

So regrading to what I understood according to the required behavior, I think the solution is simple, and no need to complicate it:所以根据需要的行为回归到我所理解的,我认为解决方案很简单,不需要复杂化:

I was looking at the pages and the script behavior and found out that the class scroll-lock is not being added to the DOM, but you can I think simply just count on the class name: responsive-menu-pro-open that is being added to the HTML element after opening the menu, So just try to set some CSS properties to this class and I think you are set to go.我正在查看页面和脚本行为,发现 class滚动锁定没有被添加到 DOM,但我认为你可以简单地依靠 class 名称:正在响应的菜单亲打开打开菜单后添加到 HTML 元素,所以只需尝试设置一些 CSS 属性到这个 class 并且我认为你设置为 ZA14394D1F91FBBA75E Please confirm.请确认。

.responsive-menu-pro-open{
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

Hope this helps as I've tried it at my own end and it worked perfectly:)希望这会有所帮助,因为我自己已经尝试过了,而且效果很好:)

The best way to solve this problem is in fact with the Wordpress plugin you are using, called Responsive Menu , which allows you to edit those options.解决此问题的最佳方法实际上是使用您正在使用的 Wordpress 插件,称为Responsive Menu ,它允许您编辑这些选项。 I use it on my site, Couv's Corner .我在我的网站Couv's Corner上使用它。 Here are some trouble-shooting solutions:以下是一些故障排除解决方案:

  • Make Sure the plugin is up to date, it has updated recently and is much better.确保插件是最新的,它最近更新并且更好。
  • Sub-Menus (Menu Items nested under parent categories) are the best.子菜单(嵌套在父类别下的菜单项)是最好的。 Use them anywhere necessary.在任何需要的地方使用它们。 Customize this in the "Menus" Page of your admin dashboard.在管理仪表板的“菜单”页面中自定义此项。
  • Check your theme.检查你的主题。 Kadence WP is a good one. Kadence WP是一个不错的选择。 Play around some, b/c your theme may have a conflict.玩一些,b/c 你的主题可能有冲突。
  • Try running a site database/file optimization and clearing your cache/cdn if you use them.如果您使用它们,请尝试运行站点数据库/文件优化并清除缓存/cdn。 That may help you fix the issue.这可能会帮助您解决问题。 Hope this helps.希望这可以帮助。 Be sure to check out the plugin, as well as how I have it set on my site , to see what you think.请务必检查插件,以及我如何在我的网站上设置它,看看你的想法。

Be in Touch!保持联系!

Hayden Couvillon,海登·库维隆,

Author, Host, - Couv's Corner作者,主持人,- Couv's Corner

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM