【问题标题】:Check whether ancestor of element is fixed检查元素的祖先是否固定
【发布时间】:2013-06-30 12:54:21
【问题描述】:

我有一个具有固定导航栏的网站,我想使用 Zurb Joyride 将提示附加到导航栏中的元素。问题是当页面滚动时,导航栏保持不变,但工具提示却没有。

我尝试将工具提示附加到导航栏中的元素(而不是 body),但出现了奇怪的渲染问题。在包含提示的div 上设置position: fixed 似乎可行,但我想知道是否有一种简单的方法可以以编程方式检测元素是否不可滚动,因为它包含在一个固定位置的容器中,这样我就可以检测何时将 Joyride 提示设置为固定。有什么建议吗?

【问题讨论】:

    标签: javascript zurb-joyride


    【解决方案1】:

    这是一种纯 JavaScript 方法。它遍历所有偏移父节点,直到找到一个固定的父节点(或根本没有)。

    function isFixed(elem){
        do{
          if(getComputedStyle(elem).position == 'fixed') return true;
        }while(elem = elem.offsetParent);
        return false;
    }
    

    如果您使用 jQuery,则需要使用 elem[0]elem.get(0) 提取节点对象。

    【讨论】:

      【解决方案2】:

      您可以使用 jQuery 来执行此操作。假设您的祖先元素是固定位置容器,为了简单起见,它有一个“祖先”类。还可以说您的后代(Joyride 提示)有一类“后代”。这两个假设都应该是您可以轻松添加到 HTML 中的内容,或者使用现有类作为不同的 jQuery 选择器。然后你可以做这样的事情来做你的检测。

      if ($(".descendant").closest(".ancestor").css("position") == "fixed") {
          // set your Joyride tip to fixed
      }
      

      更新

      由于您已经给出了更多想要做的事情,我认为问题类似于“我如何检查祖先是否具有固定位置并且没有更近的祖先滚动?”。除此之外,还要求没有一个祖先具有指定的类或 id。我将假设您的 Joyride 站点都有一个纯粹用于此示例的“joyride-stop”类。因此,要确定是否将固定位置应用于您的 Joyride 站点,您只需执行以下操作(使用 jQuery,因为 zurb joyride 将其作为依赖项):

      var jStops = $(".joyride-stop");
      
      for (var i=0; i<jStops.length; i++) {
          var pEls = jStops[i].parents();
          for (var j=0; j<pEls.length; j++) {
              if(pEls[j].css("position") == "fixed") {
                  // closest ancestor is fixed.
                  // insert code to fix your Joyride element here
                  break;
              } else if (pEls[j].css("overflow") == "scroll") {
                  // closest ancestor scrolls so just break and move on
                  break;
              }
          }
      }
      

      请注意,我在这里只检查了overflow css 属性。如果你想变得花哨,你可以检查 overflow-x、overflow-y 和可能影响滚动是否存在的任何其他属性(例如一些其他自定义 JavaScript 小部件)。检查取决于您在页面上真正需要担心的内容,

      这就是你所追求的吗?

      【讨论】:

      • 问题是提示可能附加到任何元素上。但是该元素的任何祖先都可能恰好是position: fixed。我认为向碰巧有提示的每个元素添加样式类将是糟糕的 SoC。如果它的元素保持固定,我宁愿能够确保提示保持固定,而不会破坏标记。
      • 我只是使用类方法作为示例,而不是您没有提供代码示例来支持您的问题。如果明确提示是如何应用的,那么我可以给出更相关的答案。鉴于提示知道它们适用于哪个元素,我很确定您也可以访问该信息。然后你可以应用我上面描述的方法。最后,在你的标记中应用类是一种非常常见的方法,它几乎不会造成污染,因为这就是属性的用途
      • 很公平,但如果我手动添加类来完成这项工作,我还不如硬连线标记中的position: fixed。 Joyride 是内容标记的辅助,而我的现状解决方案的优点是它的编辑至少仅限于 Joyride 标记。我仍然必须手动维护哪些元素是固定的,而不是检测它们,但您的解决方案也有这个缺点。
      • 我修改了答案以适合我认为您需要的内容。
      • 我很久以前就遇到过这个问题,我不记得这是否解决了它。但是阅读更新后的答案,听起来还不错。
      【解决方案3】:

      这是使用 jQuery 的一种方式:

      var ancestorFixed = false;
      $element.parents().each(function () {
          ancestorFixed = ancestorFixed || ($(this).css('position') == 'fixed');
      });
      

      【讨论】:

        【解决方案4】:

        到目前为止,我所拥有的最佳解决方案是手动将提示的li 分类为具有position: fixed 的样式。

        请注意,如果更接近的祖先具有滚动内容,则具有position: fixed 祖先的元素可能仍会滚动,因此可能没有通用的静态方法通过检测单个position: fixed 祖先来解决我的问题。我认为理想的解决方案是在滚动时动态更新提示位置,以确保它相对于目标元素保持固定。

        【讨论】:

          猜你喜欢
          • 2014-09-15
          • 1970-01-01
          • 2022-12-17
          • 2019-05-03
          • 1970-01-01
          • 2011-10-28
          • 1970-01-01
          • 2016-04-25
          相关资源
          最近更新 更多