【问题标题】:Ignore visibility of outer elements and select the first visible child element in a jQuery selector忽略外部元素的可见性并在 jQuery 选择器中选择第一个可见的子元素
【发布时间】:2016-04-29 07:34:23
【问题描述】:

HTML:

<div class="outer">
  <div id="inner1" class="inner" style="display: none"></div>
  <div id="inner2" class="inner"></div>
  <div id="inner3" class="inner"></div>
</div>

JavaScript (fiddle):

var $first_visible = $("div.inner:visible:first");

这将返回第一个可见的内部 div,即inner2

但是,一旦外部 div 被隐藏(假设我想稍后将其淡入):

<div class="outer" style="display: none">
  <div id="inner1" class="inner" style="display: none"></div>
  <div id="inner2" class="inner"></div>
  <div id="inner3" class="inner"></div>
</div>

所有内部 div 被认为是隐藏的,选择器不再返回 inner2

我需要如何修改我的 jQuery 选择器以忽略容器的可见性?

【问题讨论】:

  • 你不能,如果元素被隐藏了,它就被隐藏了,隐藏的父元素中的元素也被隐藏了。
  • 尝试类似的方法:jsfiddle.net/jabark/p80ttvtb/4

标签: javascript jquery html css jquery-selectors


【解决方案1】:

正如adeno所说,一旦隐藏起来,你就无能为力了。

但是,您可以事先检查,不管它是否显示,如果它被隐藏,则再次隐藏它

var wasVisible = $(".outer").is(':visible');

$(".outer").show();

var $first_visible = $("div.inner:visible:first");

if (!wasVisible) {
  $(".outer").hide();
}

console.log($first_visible.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="outer" style="display: none">
  <div id="inner1" class="inner" style="display: none"></div>
  <div id="inner2" class="inner"></div>
  <div id="inner3" class="inner"></div>
</div>

【讨论】:

    【解决方案2】:

    如果我理解正确的话,你可以像这样使用 CSS 来模拟父对象被隐藏的效果。

    HTML

    <div class="outer hide">
        <div id="inner1" class="inner hide">Inner 1</div>
        <div id="inner2" class="inner">Inner 2</div>
        <div id="inner3" class="inner">Inner 3</div>
    </div>
    

    CSS

    .hide {
        background: rgba(0,0,0,0);
        color: rgba(0,0,0,0);
        border-color: rgba(0,0,0,0);
    
        // For an SVG
        fill: rgba(0,0,0,0);
        stroke-opacity: 0;
    }
    

    您不能使用可见性/显示/不透明度属性的原因是因为正如@Umesh 提到的那样,所有后代元素也将使其显示/可见性/不透明度不可见,就好像该元素不存在一样文档树。

    但是使用这种方法,您将元素的 alpha 设置为 0,这不会影响后代,除非他们为这些属性设置了 inherit

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      编写两个类:第一个显示,最后一个隐藏。 有了它,您可以选择所有“可见”的 div,即使父级是“隐藏的”

      var $first_visible = $("div.inner.enable");
      console.log($first_visible);
      $("div#result").text($first_visible[0].id);
      .disable{
        display : none;
      }
      
      .enable{
        display : block;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div class="outer disable">
        <div id="inner1" class="inner disable">1</div>
        <div id="inner2" class="inner enable">2</div>
        <div id="inner3" class="inner enable">3</div>
      </div>
      
      <div id="result"></div>

      【讨论】:

        【解决方案4】:

        一种选择是显示父元素,检查第一个可见元素,然后再次隐藏父元素。

        或者,由于元素具有内联 CSS,您可以根据 display 属性是否设置为 none 来过滤元素,然后在过滤后的集合中检索第一个元素:

        Updated Example

        var $first_visible = $(".inner").filter(function () {
          return this.style.display !== 'none';
        }).first();
        

        var $first_visible = $(".inner").filter(function () {
          return this.style.display !== 'none';
        }).first();
        
        $("div#result").text('First visible: #' + $first_visible[0].id);
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div class="outer" style="display: none;">
          <div id="inner1" class="inner" style="display: none"></div>
          <div id="inner2" class="inner"></div>
          <div id="inner3" class="inner"></div>
        </div>
        
        <div id="result"></div>

        但是,更好的方法是使用.getComputedStyle() method 检查元素的计算样式。这样做,您可以确定元素的display 是否设置为none,即使该元素没有内联CSS。

        Updated Example

        var $first_visible = $(".inner").filter(function () {
          return window.getComputedStyle(this, null).getPropertyValue('display') !== 'none';
        }).first();
        

        var $first_visible = $(".inner").filter(function () {
          return window.getComputedStyle(this, null).getPropertyValue('display') !== 'none';
        }).first();
        
        $("div#result").text('First visible: #' + $first_visible[0].id);
        #inner1 { display: none; }
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div class="outer" style="display: none;">
          <div id="inner1" class="inner"></div>
          <div id="inner2" class="inner"></div>
          <div id="inner3" class="inner"></div>
        </div>
        
        <div id="result"></div>

        【讨论】:

          【解决方案5】:

          我的建议是使用过滤功能,但只选择第一个可见元素(但这也是隐藏的,因为父元素是隐藏的):

          var $first_visible = $('div.inner').filter(function() { return !(this.style.visibility != '' || this.style.display != ''); })。第一的();

          $(function () {
            var $first_visible = $('div.inner').filter(function() {
              return !(this.style.visibility != '' || this.style.display != '');
            }).first();
            $('body').append('<p>' + $first_visible.attr('id') + '</p>');
          });
          <script src="http://code.jquery.com/jquery-1.11.3.js"></script>
          
          
          <div class="outer" style="display: none">
              <div id="inner1" class="inner" style="display: none;"></div>
              <div id="inner2" class="inner"></div>
              <div id="inner3" class="inner"></div>
          </div>

          【讨论】:

            【解决方案6】:

            看到这里我已经检查了忽略第一个 div 的样式属性。并检查隐藏选择器以获取所有其他 div。

            $(document).ready(function(){
              var currElements=$('.inner[style!="display: none"]:hidden'); // Here you are get two div with id inner2 and inner3
              alert(currElements[0].id); // First div
              alert(currElements[1].id); // First div
              });
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
            <div class="outer" style="display: none">
              <div id="inner1" class="inner" style="display: none">Inner 1</div>
              <div id="inner2" class="inner">Inner 2</div>
              <div id="inner3" class="inner">Inner 3</div>
            </div>

            【讨论】:

              【解决方案7】:

              MDN 说:

              当您使用 none 时,所有后代元素的显示也会关闭。文档呈现为好像该元素在文档树中不存在。

              因此,无论 HTML 元素是父元素的子元素,都不会在 HTML 页面中呈现。

              此外,在父元素上应用的任何样式都不会在 HTML 页面中呈现。

              为了实现你想要的,如果你认为你的 HTML 元素应该在文档树中,那么尝试使用 CSS 可见性属性。例如:

              <div class="outer" style="visibility: hidden">
                <div id="inner1" class="inner" style="display: none"></div>
                <div id="inner2" class="inner" style="visibility: visible"></div>
                <div id="inner3" class="inner"></div>
              </div>
              

              JS Fiddle

              【讨论】:

                【解决方案8】:

                获取一个标志值并循环每个div.inner 以获得第一个可见元素。然后检查它的 css 属性。

                下面是测试代码:

                var isValid=true;
                $("div.inner").each(function() {
                    if($(this).css("display") == "block" && isValid) {
                        $("div#result").text($(this).attr('id'));isValid=false;
                    }
                });
                

                【讨论】:

                  猜你喜欢
                  • 2010-10-24
                  • 2015-03-10
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-06-27
                  相关资源
                  最近更新 更多