【问题标题】:How to exclude undesired descendants?如何排除不受欢迎的后代?
【发布时间】:2011-01-11 23:18:37
【问题描述】:

我有一个元素包含n可点击句柄和n可显示元素的情况:

<div class="revealer">
  <div class="hotspot">
    <a class="handle" href="javascript:;">A</a>
    <div class="reveal">
      <p>Content A.</p>
    </div>
    <div class="reveal">
      <p>Content B.</p>
    </div>
  </div>
</div>

当我单击“处理”时,它会显示两个“显示”元素。这工作正常。这段代码被放到创建者想要的任何地方的给定文档中。包括...在另一个 &lt;div class="reveal"&gt;&lt;/div&gt; 元素中。嵌套这些显示对象的能力是合理的,对我来说很有用。

我坚持的是,一种仅处理直接&lt;div class="reveal"&gt;&lt;/div&gt; 元素而不是嵌套元素的体面方法(否则单击外部句柄会显示所有嵌套显示)。

下面是示例结构:


<div class="revealer">
  <div class="hotspot">
    <a class="handle" href="javascript:;">A</a>
    <div class="reveal">
      <p>Content A.</p>
    </div>
    <div class="reveal">

        <p>Content B.</p>

        <!-- nested revealer -->
        <div class="revealer">
          <div class="hotspot">
            <a class="handle" href="javascript:;">A</a>
            <div class="reveal">
              <p>Sub-content A.</p>
            </div>
            <div class="reveal">
              <p>Sub-content B.</p>
            </div>
          </div>
        </div>
        <script type="text/javascript"> // a setup script which instantiates a Module object for this revealer, which controls all revealing </script>

    </div>
  </div>
</div>
<script type="text/javascript"> // a setup script, which instantiates a Module object for this revealer, which controls all revealing </script>

我大量使用 YUI2.8.2 框架,所以现在我有一个测试,当你点击一个句柄来收集一组它自己的显示器并显示它们,但不包括嵌套显示,应该由他们自己操作实例化模块,而不是父模块。

Javascript测试如下:

    // grab all 'reveal' elements to show
    var reveals = yd.getElementsBy(function(el){
            if( yd.hasClass(el, REVEAL_CLASS) && pObj.isChild( el ) ){
                return true ;
            }
            return false;
    }, null, this.root() );


    // the test method above is "isChild( el )", the 'el' arg is a 'handle' inside a 'hotspot', so I have...

isChild: function( el )
{
    var ancestor = yd.getAncestorBy( el, function(nestedEl){
        return yd.hasClass(nestedEl, REVEALER_CLASS);
    });

    // ancestor is the immediate parent 'reveal' element
    var forefather = yd.getAncestorBy( ancestor, function(nestedEl){
        return yd.hasClass(nestedEl, REVEALER_CLASS);
    });

    // forefather is 
    if(forefather){
        // Yuck yuck yuck, get rid of this dependency on a custom className :(
        if(!yd.hasClass(this.getRoot(), 'revealer-nested') ){
            return false ;
        }
    }
    return true ;
},

但我所能做的就是向嵌套的revealer 元素添加一个新的类名revealer-nested...但我真的不想这样做,因为这些对象应该存在于它们自己的上下文中,而不关心或受父级揭示者的影响。

...我希望这不是 tmi,请询问任何必需的问题等以获取更多信息 - 我可能错过了一些上下文信息,因为我正处于重构此模块的中间。

提前非常感谢。

编辑: 同样重要的是,我不要开始依赖诸如 parentNode、childNode[x]、nextSibling 等后代属性......因为目前这个模块非常灵活,因为它的“显示”和“处理”元素可以驻留在其他标记并且仍然是目标 - 只要在“热点”内找到它们。

【问题讨论】:

  • Hrm,代码着色对我来说看起来不太合适,而且我看不到任何标记错误 - 但我确实手动输入了 HTML 的删节块 - 请放心,它是有效的代码在我的情况下。
  • 也许我理解错了,但您只需要显示与handle 处于同一级别(因此,兄弟姐妹)的reveal 对象。不过我不知道 YUI。
  • 你是对的,我没有在问题中表达这一点 - 但实际上我已经以这样一种方式构建了我的模块,即显示元素和句柄理论上可以位于 x 级别的标记内并且仍然被正确定位。所以我使用 YUI 只抓取我需要的元素,而不是依赖于 parentNode、nextSibling 等节点定位。我将把它添加到问题中。

标签: javascript module filter generics descendant


【解决方案1】:

有一个 CSS3 选择器 :not() 允许您从选择中过滤掉元素。我知道 jQuery 可以通过 CSS3 选择器选择一组元素,例如:

$('.revealer:not(.revealer > .revealer)')

我认为这可以作为一个选择器,只选择“revealer”类的元素,这些元素不是“revealer”类的子元素。

这一切都取决于 YUI 是否能够支持 CSS3 选择器来选择元素集(如果你肯定只使用 YUI)。

这有帮助吗?我想这就是你要问的......

【讨论】:

  • 哦,我的错,这在 IE6 中可以工作吗? (大声笑,哭泣,)。实际上,我什至重构这个模块的原因之一是包括我们自己的小得多的小部件,它只使用 YUI 基础框架——为了减少 HTTP 请求的明确目的(顺便说一句,不能使用 YUI 组合)。我将 4 个模块组合成一个来实现这一点,所以添加另一个 lib 依赖项(jquery/other)不是最好的选择......但我想如果没有任何可用的工作,它可能必须这样做。请注意,我不一定需要 YUI 代码作为答案,只需要一般逻辑即可,我会对其进行 YUI 处理。
  • 不过,不要让你出轨,是的,这在理论上是我想要的,只要这将是强烈的跨浏览器。
  • 当 jQuery 执行此操作时,它实际上并不依赖于浏览器中的 CSS3 - 它使用 JavaScript 实现功能。从 jQuery 的网站上,整个 jQuery 库兼容:IE 6.0+、FF 2+、Safari 3.0+、Opera 9.0+、Chrome。此外,YUI 可能在某处内置了 CSS3 选择器集......但我不确定 YUI 的跨浏览器兼容性,因为我从未使用过它。
  • Gotchya,我犯的愚蠢错误。 YUI 有 Selector 实用程序,我现在正在使用它。我已经尝试了一些东西,例如:“#_revealerEl_0 .handle:not(#_revealerEl_0 .reveal .handle)”(动态应用的 'revealer' div 的 id 属性)。它所做的是继续选择显示中的所有句柄,而不是基于 :not 选择器进行排除。我目前正在为此寻找示例用法,但运气不佳 - 你有没有像 not() 这样的 CSS3 选择器的不错资源,因为我认为我们快到了!
  • 在我获得有关 YUI2.8.1 选择器实用程序的更多信息之前,我已经包含了 jquery - 结果与 YUI 相同,所以我会说我的选择不正确。这是我结合选择的字符串:#_revealerEl_0 .handle:not(#_revealerEl_0 .reveal .handle)。所以我的想法是“_revealerEl_0 中的所有句柄,除了在其嵌套的显示器中找到的任何句柄”。
猜你喜欢
  • 2021-02-20
  • 2021-10-11
  • 2016-03-10
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
相关资源
最近更新 更多