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

时间:2011-07-22 15:37:10

标签: javascript jquery arrays dom

我有一个使用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")  
    }           
}

如果您查看下面的代码“//检查我们是否需要对数组长度进行重新计算。”,您将看到我根据显示器剥离文本节点的位置以及是否或者不定义对象。我正在检查长度而不是未定义,因为typeof == undefined由于某种原因根本不起作用。显然,事情仍然在滑落。

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

我为这么大的帖子道歉!

提前致谢

3 个答案:

答案 0 :(得分:1)

我修改了你的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()并决定该做什么。

答案 1 :(得分:0)

我无法完全了解您的代码,但最可能的问题是您要从数组中删除项目,但之后不会缩小数组。只需删除项目就会返回“未定义”,并且不会折叠数组。

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

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

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

  3. 我希望这是一种帮助。

答案 2 :(得分:0)

在另一篇文章中找到答案。

Remove empty elements from an array in Javascript

结束使用答案的第二个选项,它运作正常。