javascript不从数组中删除未定义的对象

发布于 2024-11-26 01:34:22 字数 3462 浏览 1 评论 0原文

我有一个使用 JS 的页面内文本搜索,如下所示:

$.fn.eoTextSearch = function(pat) {
    var out = []
    var textNodes = function(n) {
        if (!window['Node']) {
            window.Node = new Object();
            Node.ELEMENT_NODE = 1;
            Node.ATTRIBUTE_NODE = 2;
            Node.TEXT_NODE = 3;
            Node.CDATA_SECTION_NODE = 4;
            Node.ENTITY_REFERENCE_NODE = 5;
            Node.ENTITY_NODE = 6;
            Node.PROCESSING_INSTRUCTION_NODE = 7;
            Node.COMMENT_NODE = 8;
            Node.DOCUMENT_NODE = 9;
            Node.DOCUMENT_TYPE_NODE = 10;
            Node.DOCUMENT_FRAGMENT_NODE = 11;
            Node.NOTATION_NODE = 12;
        }
        if (n.nodeType == Node.TEXT_NODE) {
            var t = typeof pat == 'string' ?
            n.nodeValue.indexOf(pat) != -1 :
            pat.test(n.nodeValue);
            if (t) {
                out.push(n.parentNode)
            }
        }
        else {
            $.each(n.childNodes, function(a, b) {
                textNodes(b)
            })
        }
    }
    this.each(function() {
        textNodes(this)
    })
    return out
};

并且我能够隐藏表中的列和行。当我提交搜索并获得突出显示的结果时,在这种情况下,找到的文本节点的数组长度将为6,但页面上只会突出显示3个。当您将数组输出到控制台时,您会得到以下结果:

因此,您得到了我期望的 3 个标签,但是您看到该数组实际上由 [span,undefined,span,undefined,undefined,span] 组成。因此给了我 6 的长度。

<span>
<span>
<span>
[span, undefined, span, undefined, undefined, span]

我不知道为什么当我检查它们时它没有删除所有未定义的文本节点。这是我为该功能所获得的内容。

performTextSearch = function(currentObj){
    if($.trim(currentObj.val()).length > 0){
        var n = $("body").eoTextSearch($.trim(currentObj.val())),
            recordTitle = "matches",
            arrayRecheck = new Array(),
            genericElemArray = new Array()
        if(n.length == 1){
            recordTitle = "match"
        }

        //check to see if we need to do a recount on the array length. 
        //if it's more than 0, then they're doing a compare and we need to strip out all of the text nodes that don't have a visible parent.
        if($(".rows:checked").length > 0){
            $.each(n,function(i,currElem){
                if($(currElem).length != 0 && typeof currElem != 'undefined'){
                    if($(currElem).closest("tr").is(":visible") || $(currElem).is(":visible")){
                        //remove the element from the array
                        console.log(currElem)
                        arrayRecheck[i] = currElem
                    }
                }
            })
        }
        if(arrayRecheck.length > 0){
            genericElemArray.push(arrayRecheck)
            console.log(arrayRecheck)
        }
        else{
            genericElemArray.push(n)    
        }
        genericElemArray = genericElemArray[0]
        $("#recordCount").text(genericElemArray.length + " " +recordTitle)
        $(".searchResults").show()
        for(var i = 0; i < genericElemArray.length; ++i){ 
            void($(genericElemArray[i]).addClass("yellowBkgd").addClass("highLighted"))
        }   
    }
    else{
        $(".highLighted").css("background","none")  
    }           
}

如果您查看下面的代码“//check to see if we need to do a recount on the array length.”,您会看到我在哪里根据显示剥离文本节点以及是否对象被定义。我正在检查长度而不是未定义,因为由于某种原因 typeof == undefined 根本不起作用。显然,事情仍在进展。

知道为什么我仍然在数组中得到未定义的对象吗?

对于这么大的帖子,我深表歉意!

提前致谢

I've got an in page text search using JS, which is here:

$.fn.eoTextSearch = function(pat) {
    var out = []
    var textNodes = function(n) {
        if (!window['Node']) {
            window.Node = new Object();
            Node.ELEMENT_NODE = 1;
            Node.ATTRIBUTE_NODE = 2;
            Node.TEXT_NODE = 3;
            Node.CDATA_SECTION_NODE = 4;
            Node.ENTITY_REFERENCE_NODE = 5;
            Node.ENTITY_NODE = 6;
            Node.PROCESSING_INSTRUCTION_NODE = 7;
            Node.COMMENT_NODE = 8;
            Node.DOCUMENT_NODE = 9;
            Node.DOCUMENT_TYPE_NODE = 10;
            Node.DOCUMENT_FRAGMENT_NODE = 11;
            Node.NOTATION_NODE = 12;
        }
        if (n.nodeType == Node.TEXT_NODE) {
            var t = typeof pat == 'string' ?
            n.nodeValue.indexOf(pat) != -1 :
            pat.test(n.nodeValue);
            if (t) {
                out.push(n.parentNode)
            }
        }
        else {
            $.each(n.childNodes, function(a, b) {
                textNodes(b)
            })
        }
    }
    this.each(function() {
        textNodes(this)
    })
    return out
};

And I've got the ability to hide columns and rows in a table. When I submit a search and get the highlighted results, there would be in this case, the array length of the text nodes found would be 6, but there would only be 3 highlighted on the page. When you output the array to the console you get this:

So you get the 3 tags which I was expecting, but you see that the array is actually consisting of a [span,undefined,span,undefined,undefined,span]. Thus giving me the length of 6.

<span>
<span>
<span>
[span, undefined, span, undefined, undefined, span]

I don't know why it's not stripping out all of the undefined text nodes when I do the check for them. Here's what I've got for the function.

performTextSearch = function(currentObj){
    if($.trim(currentObj.val()).length > 0){
        var n = $("body").eoTextSearch($.trim(currentObj.val())),
            recordTitle = "matches",
            arrayRecheck = new Array(),
            genericElemArray = new Array()
        if(n.length == 1){
            recordTitle = "match"
        }

        //check to see if we need to do a recount on the array length. 
        //if it's more than 0, then they're doing a compare and we need to strip out all of the text nodes that don't have a visible parent.
        if($(".rows:checked").length > 0){
            $.each(n,function(i,currElem){
                if($(currElem).length != 0 && typeof currElem != 'undefined'){
                    if($(currElem).closest("tr").is(":visible") || $(currElem).is(":visible")){
                        //remove the element from the array
                        console.log(currElem)
                        arrayRecheck[i] = currElem
                    }
                }
            })
        }
        if(arrayRecheck.length > 0){
            genericElemArray.push(arrayRecheck)
            console.log(arrayRecheck)
        }
        else{
            genericElemArray.push(n)    
        }
        genericElemArray = genericElemArray[0]
        $("#recordCount").text(genericElemArray.length + " " +recordTitle)
        $(".searchResults").show()
        for(var i = 0; i < genericElemArray.length; ++i){ 
            void($(genericElemArray[i]).addClass("yellowBkgd").addClass("highLighted"))
        }   
    }
    else{
        $(".highLighted").css("background","none")  
    }           
}

If you look at the code below "//check to see if we need to do a recount on the array length. ", you'll see where I'm stripping out the text nodes based off of the display and whether or not the object is defined. I'm checking the length instead of undefined because the typeof == undefined wasn't working at all for some reason. Apparently, things are still slipping by though.

Any idea why I'm still getting undefined objects in the array?

My apologies for such a big post!

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

美人如玉 2024-12-03 01:34:22

我修改了您的 eoTextSearch() 函数,以删除对全局变量的依赖关系以换取闭包:

$.fn.extend({
  // helper function
  // recurses into a DOM object and calls a custom function for every descendant
  eachDescendant: function (callback) {
    for (var i=0, j=this.length; i<j; i++) {
      callback.call(this[i]);
      $.fn.eachDescendant.call(this[i].childNodes, callback);
    }
    return this;
  },
  // your text search function, revised
  eoTextSearch: function () {
    var text = document.createTextNode("test").textContent 
               ? "textContent" : "innerText";
    // the "matches" function uses an out param instead of a return value
    var matches = function (pat, outArray) {
      var isRe = typeof pat.test == "function";
      return function() {
        if (this.nodeType != 3) return; // ...text nodes only
        if (isRe && pat.test(this[text]) || this[text].indexOf(pat) > -1) {
          outArray.push(this.parentNode);
        }
      }
    };
    // this is the function that will *actually* become eoTextSearch()
    return function (stringOrPattern) {
      var result = $(); // start with an empty jQuery object
      this.eachDescendant( matches(stringOrPattern, result) );
      return result;
    }
  }()  // <- instant calling is important here
});

然后您可以执行如下操作:

$("body").eoTextSearch("foo").filter(function () {
  return $(this).closest("tr").is(":visible");
});

从搜索结果中删除不需要的元素。不需要“重新计算数组长度”。或者您直接使用 each() 并决定要做什么。

I've modified your eoTextSearch() function to remove dependencies on global variables in exchange for closures:

$.fn.extend({
  // helper function
  // recurses into a DOM object and calls a custom function for every descendant
  eachDescendant: function (callback) {
    for (var i=0, j=this.length; i<j; i++) {
      callback.call(this[i]);
      $.fn.eachDescendant.call(this[i].childNodes, callback);
    }
    return this;
  },
  // your text search function, revised
  eoTextSearch: function () {
    var text = document.createTextNode("test").textContent 
               ? "textContent" : "innerText";
    // the "matches" function uses an out param instead of a return value
    var matches = function (pat, outArray) {
      var isRe = typeof pat.test == "function";
      return function() {
        if (this.nodeType != 3) return; // ...text nodes only
        if (isRe && pat.test(this[text]) || this[text].indexOf(pat) > -1) {
          outArray.push(this.parentNode);
        }
      }
    };
    // this is the function that will *actually* become eoTextSearch()
    return function (stringOrPattern) {
      var result = $(); // start with an empty jQuery object
      this.eachDescendant( matches(stringOrPattern, result) );
      return result;
    }
  }()  // <- instant calling is important here
});

And then you can do something like this:

$("body").eoTextSearch("foo").filter(function () {
  return $(this).closest("tr").is(":visible");
});

To remove unwanted elements from the search result. No "recounting the array length" necessary. Or you use each() directly and decide within what to do.

入画浅相思 2024-12-03 01:34:22

我无法完全理解您的代码,但最可能的问题是您正在从数组中删除项目,但之后不会缩小数组。简单地删除项目将返回“未定义”,并且不会折叠数组。

我建议您执行以下操作之一:

  1. 将数组复制到新数组,但仅复制那些未定义的项目

  2. 仅使用那些未定义的数组项。

我希望这能有所帮助。

I cannot entirely get my head around your code, but the most likely issue is that you are removing items from the array, but not shrinking the array afterwards. Simply removing items will return you "undefined", and will not collapse the array.

I would suggest that you do one of the following:

  1. Copy the array to a new array, but only copying those items that are not undefined

  2. Only use those array items that are not undefined.

I hope this is something of a help.

无人问我粥可暖 2024-12-03 01:34:22

在另一个帖子里找到了答案。

从 Javascript 数组中删除空元素

最终使用答案的第二个选项,效果很好。

Found the answer in another post.

Remove empty elements from an array in Javascript

Ended up using the answer's second option and it worked alright.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文