【问题标题】:Is there a jQuery selector function that can reference relative elements?是否有可以引用相关元素的 jQuery 选择器函数?
【发布时间】:2014-01-11 07:55:38
【问题描述】:

以下是一些示例,我希望与 $ 一起使用:

$(':target', element); // Should return element
$(':parent', element); // Should return parent of element
$(':parent textarea', element); // Should return textareas within parent of element

我不想使用parent 方法的原因是因为选择器是动态的,我不想解析它。

编辑

这是一个具体的例子。

HTML:

<div>
    <span data-hide=":parent span:eq(1)">Span 1</span>
    <span>Span 2</span>
</div>

JavaScript:

$('[data-hide]').on('click', function()
{
    var selector = $(this).attr('data-hide');
    $(selector, $(this)).hide();
});

如果$(称为context)和:parent 伪选择器的第二个参数按我预期的方式工作,单击“跨度1”将隐藏“跨度2”。

但事实并非如此。那么如何编写这个函数,以便可以使用任何合理的绝对或相对选择器呢?

【问题讨论】:

  • 不...没有名为:parent:target的选择器...你为什么想要它
  • 听起来您应该查看jQuery API
  • 你想从 $(':target', element) 得到的内容与绑定事件回调中的 $(this) 基本相同。
  • @Arun P Johny:实际上,有,只是他们不按要求做。
  • @BoltClock 是的,我就是这个意思

标签: jquery jquery-selectors


【解决方案1】:

我有类似的要求(基本上使用单个字符串选择器在 DOM 中向上然后向下搜索),在深入研究选择器的工作原理后,我发现这对于普通选择器是不可能的,因为选择器元素的评估是 从右到左,而您需要从左到右 才能使您的建议发挥作用。我能够制作一个自定义选择器,它可以有一个:this 引用,它可以让你进行类似的搜索,包括:has(:this)。我在Is it possible to create custom jQuery selectors that navigate ancestors? e.g. a :closest or :parents selector这里重复了我的回答

基于大量的 cmets,以及关于为什么这是不可能的的详细解释,我突然想到,我想要的目标可以通过 $(document).find() 来实现,但有一些 目标元素。也就是说,在选择器中以某种方式定位原始查询元素。

为此,我想出了以下:this 选择器,它的工作原理是这样的(没有双关语):

// Find all labels under .level3 classes that have the .starthere class beneath them
$('.starthere').findThis('.level3:has(:this) .label')

这使我们现在可以有效地在单个选择器字符串中向上搜索 DOM,然后向下搜索到相邻的分支! 即它执行与此相同的工作(但在单个选择器中):

$('.starthere').parents('.level3').find('.label')

步骤:

1 - 添加一个新的jQuery.findThis 方法

2 - 如果选择器有 :this,则替换为 id 搜索并从 document 进行搜索

3 - 如果选择器不包含:this 进程,通常使用原始find

4 - 使用 $('.target').find('.ancestor:has(:this) .label') 之类的选择器进行测试,以在目标元素的祖先中选择标签

这是基于 cmets 的修订版本,它不会替换现有的 find 并使用生成的唯一 ID。

JSFiddle:http://jsfiddle.net/TrueBlueAussie/z3vwk1ko/36/

// Add findThis method to jQuery (with a custom :this check)
jQuery.fn.findThis = function (selector) {
    // If we have a :this selector
    if (selector.indexOf(':this') > 0) {
        var ret = $();
        for (var i = 0; i < this.length; i++) {
            var el = this[i];
            var id = el.id;
            // If not id already, put in a temp (unique) id
            el.id = 'id'+ new Date().getTime();
            var selector2 = selector.replace(':this', '#' + el.id);
            ret = ret.add(jQuery(selector2, document));
            // restore any original id
            el.id = id;
        }
        ret.selector = selector;
        return ret;
    }
    // do a normal find instead
    return this.find(selector);
}

// Test case
$(function () {
    $('.starthere').findThis('.level3:has(:this) .label').css({
        color: 'red'
    });
});

已知问题:

  • 这会在没有id 属性开头的目标元素上留下一个空白的id 属性(这不会​​导致问题,但不像我想要的那样整洁)

    1234563这段代码。

这是基于对 jQuery/Sizzle 源代码的 6 小时奴役,所以要温柔。总是很高兴听到改进这个替换 find 的方法,因为我是 jQuery 内部的新手 :)

然后您可以通过以下方式解决您最初的问题:

<div>
    <span data-hide="div:has(:this) span:eq(1)">Span 1</span>
    <span>Span 2</span>
</div>

JavaScript:

$('[data-hide]').on('click', function()
{
    var selector = $(this).attr('data-hide');
    $(this).findThis(selector).hide();
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    相关资源
    最近更新 更多