javascript - 自定义 jQuery 选择器返回所有元素的匹配项

标签 javascript jquery jquery-selectors

我正在尝试组合一个自定义 jquery 选择器来匹配 Asp.net 中的 asp 客户端 ID。我正在处理这两个博客条目 here 中的信息和 here

问题是我现在返回页面上每个元素的匹配项。我有点知道为什么(因为我每次思考时都会查询所有节点),但我的大脑已经完全疲惫不堪,我已经将自己编码为提交。

如果有人能找出问题所在并给我一些指示,我将非常感激。

选择器的用法如下:

$("input:clientID(TextBox1)")

干杯!

编辑:到目前为止我已经得到了这段代码,但这将返回以给定 id 结尾的所有节点。

 (function ($) {
    $.expr[":"].clientID = function (objNode, intStackIndex, arrProperties, arrNodeStack) {

        var keyValue, tName, $node, len, id;

        if (arrProperties[3]) {

            // Split into array (name,value):
            keyValue = arrProperties[3];

            // Check to see whether a tag node has been supplied.
            if (objNode) {

                // Get the name.
                tName = objNode.tagName;
                $node = $(objNode);
                id = $node.attr("id");

                if ((id.lastIndexOf(keyValue) === id.length - keyValue.length) && ($node.is(":first"))) {
                    return true;
                }
                else if (id === keyValue) {
                    return true;
                }
                else {

                    return false;
                }

            } else {

                // No node supplied so will use the ends with attribute selector.
                return $("[id$=\"_" + keyValue + "\"]").first().length > 0;
            }

        } else {

            // If we have made it this far, then we found no
            // match. Return false to indicate that this node
            // did not match our selector.
            return false;
        }
    };

} (jQuery));

最佳答案

我认为您误解了 jQuery 选择器的工作原理。以下是它们的工作原理。假设您使用以下查询:

$("input:clientID(TextBox1)");

jQuery 首先查找所有输入元素,然后针对每个元素询问您的函数是否应包含它。因此,如果您的页面有 10 个 input 元素,那么您的函数将被调用 10 次。

您不必自己查询 DOM

有了这个理解,你就可以更容易地判断节点的 id 是否包含 _TextBox1

(function ($) {
    $.expr[":"].clientID = function(objNode, intStackIndex, arrProperties, arrNodeStack) {
        // we need to something to query
        if( ! arrProperties[3] ) return false; 
        return objNode.id.indexOf( "_" + arrProperties[3] ) !== -1;
    };
} (jQuery));

我将把 ASP.net 的细节留给您,因为我不熟悉 ASP.net clientID 的生成方式。然而,根据我的理解,您也可以使用内置的 jQuery 选择器实现相同的功能(正如其他人提到的)。

编辑 - 查找 ASP.net 格式的 ID

要选择可能是“xxx_xxx_clientID”或“clientID”的 ID,可以将代码修改为:

var testID = arrProperties[3];
if( objNode.id == testID ) return true;

// ends with code
testID = "_" + testID;
var lastIndex = objNode.id.lastIndexOf(testID);
return lastIndex !== -1 && lastIndex == (objNode.id.length - testID.length);

编辑 2 - 仅查找第一个匹配的元素

为了仅匹配第一个结果,您可以在找到某些内容时设置一个标志变量。这应该比使用 James 的解决方案更快,但不太干净。

(function ($) {
    // assign the clientID filter with a self-executing anonymous function
    $.expr[":"].clientID = (function(){
        // create a "private" flag variable
        var alreadyFound = false;

        return function(objNode, intStackIndex, arrProperties, arrNodeStack) {
            if( intStackIndex === 0 ) alreadyFound = false;
            if( alreadyFound ) return false;

            var testID = arrProperties[3];
            if( objNode.id == testID){
                alreadyFound = true;
            } else {
                // ends with code
                testID = "_" + testID;
                var lastIndex = objNode.id.lastIndexOf(testID);
                alreadyFound = lastIndex !== -1 && lastIndex == (objNode.id.length - testID.length);
            }

            return alreadyFound;
        };

    })();
} (jQuery));

我们的 clientID 函数(没有其他人)可以通过闭包访问 alreadyFound 变量。

关于javascript - 自定义 jQuery 选择器返回所有元素的匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5652477/

相关文章:

javascript - 为多个<input>添加随机id

javascript - 在 jQuery 中调用同一对象上另一个函数中定义的函数

javascript - 隐藏客户端 API 调用

javascript - 当父级来自不同域时,使用 jQuery 在另一个 iframe 中执行 javascript 函数?

jquery - 什么更好 : data or attr?

jQuery 选择器每行的第一个 td

javascript - 如何使用 Selenium WebDriver 获取 disqus 评论 iframe 数据

jquery - 生成的 div 的数字和换行?

jquery - 第 n 个子元素,为每个 4 的倍数的元素分配样式

jQuery 选择和过滤问题