javascript - 如何过滤 QuerySelectorAll 返回的元素

标签 javascript

我正在开发一个 javascript 库,我使用此函数来匹配元素:

$ = function (a)
{
    var x;
    if (typeof a !== "string" || typeof a === "undefined"){ return a;}
    
    //Pick the quickest method for each kind of selector
    if(a.match(/^#([\w\-]+$)/))
    {
        return document.getElementById(a.split('#')[1]);
    }
    else if(a.match(/^([\w\-]+)$/))
    {
        x = document.getElementsByTagName(a);
    }
    else
    {
        x = document.querySelectorAll(a);
    }
    
    //Return the single object if applicable
    return (x.length === 1) ? x[0] : x;
};

有时我想要过滤此函数的结果,例如挑选一个 div span#id div 或其他一些相当简单的选择器.

如何过滤这些结果?我可以创建一个文档片段,并在该片段上使用 querySelectorAll 方法,还是必须诉诸手动字符串操作?

我只关心现代浏览器和 IE8+。

如果您想查看我的库的其余部分,请访问:https://github.com/timw4mail/kis-js

编辑:

为了澄清,我希望能够执行类似 $_(selector).children(other_selector) 的操作并返回与该选择器匹配的子元素。

编辑:

所以这是我对最简单选择器的潜在解决方案:

tag_reg = /^([\w\-]+)$/;
id_reg = /#([\w\-]+$)/;
class_reg = /\.([\w\-]+)$/;

function _sel_filter(filter, curr_sel)
{
    var i,
        len = curr_sel.length,
        matches = [];
    
    if(typeof filter !== "string")
    {
        return filter;
    }

    //Filter by tag
    if(filter.match(tag_reg))
    {
        for(i=0;i<len;i++)
        {
            if(curr_sell[i].tagName.toLowerCase() == filter.toLowerCase())
            {
                matches.push(curr_sel[i]);
            }
        }
    }
    else if(filter.match(class_reg))
    {
        for(i=0;i<len;i++)
        {
            if(curr_sel[i].classList.contains(filter))
            {
                matches.push(curr_sel[i]);
            }
        }
    }
    else if(filter.match(id_reg))
    {
        return document.getElementById(filter);
    }
    else
    {
        console.log(filter+" is not a valid filter");
    }
    
    return (matches.length === 1) ? matches[0] : matches;
    
}

它采用 div 等标记、id 或类选择器,并使用 curr_sel 参数返回匹配元素。

我不想求助于完整的选择器引擎,那么有更好的方法吗?

最佳答案

我认为我没有回答正确的问题。为什么要“过滤” querySelectorAll() 的结果事实上,它本身就是某种过滤器。如果查询div span甚至更好 #id div ,这些结果已经被过滤了,不是吗?

但是,您可以申请Array.prototype.filterquerySelectorAll 的静态结果如下:

var filter   = Array.prototype.filter,
    result   = document.querySelectorAll('div'),
    filtered = filter.call( result, function( node ) {
        return !!node.querySelectorAll('span').length;
    });

该代码首先会使用querySelectorAll()查询所有<div>文档中的节点。然后它将过滤 <div>至少包含 <span> 的节点。该代码没有多大意义,仅用于演示目的(以防某些 SO 成员想要创建 donk 评论)

更新

您还可以使用 Element.compareDocumentPosition 进行过滤。我还将判断 Elements 是否为 disconnected , following , preceding ,或contained 。请参阅MDC .compareDocumentPosition()

关于javascript - 如何过滤 QuerySelectorAll 返回的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6791112/

相关文章:

javascript - 解析和格式化自定义日期字符串 Moment.js

javascript - 将 iFrame 中的 JS 文件注入(inject) Google Chrome 扩展中的内容脚本

javascript - 分页时如何进行正确的搜索

javascript - 使用 CSS/JavaScript 在事件页面上突出显示事件导航菜单项,无 ID

javascript - 如何使用 Javascript 在 iframe 中设置 src

javascript - rails : View javascript object's attributes in browser's console

javascript - 在 Javascript 中找到具有最多点的最少节点的最佳方法

javascript - Google Closure Compiler 错误地删除了函数调用

javascript - 文档滚动高度减去高度

javascript - 使用 Lambda 函数在 Amazon S3 存储桶上创建缩略图