Array.prototype.filter()返回空列表

时间:2019-07-08 10:30:17

标签: javascript jquery html

我正在尝试过滤使用.siblings()方法收集的jQuery元素列表。 我有html代码:

<div>
    <div>
        <label for="username">Username</label>
        <input class="form-control username" type="text" placeholder="Username" id="username"/>
    </div>

    <div>
        <label for="Password">Password</label>
        <input class="form-control password" type="password" placeholder="Password" id="password"/>
    </div>

    <div style="text-align:center;">
         <button id="login">Login</button>
    </div>
</div>

按下按钮时,我使用以下命令收集同级div:

var elem = jQuery(this).parent('div').siblings('div:has(input)');

这将返回一个长度为2的数组(包含用户名和密码的div)。

当我然后检查该数组中的第一项是否具有带有“用户名”类的子输入标签时,以下代码将返回true。

jQuery(elem[0]).children('input').hasClass('username');

但是,当我在这种情况下过滤数组时,将返回长度为0的数组。为什么会这样?当然,数组应该包含1个元素,因为条件在第一个元素上的计算结果为true?

var filteredElem = elem.filter(div => jQuery(div).children('input').hasClass('username'));

$('#login').click(function() {

  var elem = jQuery(this).parent('div').siblings('div:has(input)');

  var filteredElem = elem.filter(div => jQuery(div).children('input').hasClass('username'));

  console.log(filteredElem.length)

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div>
    <label for="username">Username</label>
    <input class="form-control username" type="text" placeholder="Username" id="username" />
  </div>

  <div>
    <label for="Password">Password</label>
    <input class="form-control password" type="password" placeholder="Password" id="password" />
  </div>

  <div style="text-align:center;">
    <button id="login">Login</button>
  </div>
</div>

1 个答案:

答案 0 :(得分:8)

首先请注意,您正在调用jQuery filter()方法,而不是标题所暗示的本机数组filter()方法。这是因为elem拥有一个jQuery对象,而不是一个数组。

问题本身是因为传递给jQuery filter()处理函数的第一个参数是当前元素的索引,而不是对该元素本身的引用。因此,您需要将逻辑更改为:

var filteredElem = elem.filter((i, div) => ...

$('#login').click(function() {
  var elem = jQuery(this).parent('div').siblings('div:has(input)');

  var filteredElem = elem.filter((i, div) => jQuery(div).children('input').hasClass('username'));

  console.log(filteredElem.length);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div>
    <label for="username">Username</label>
    <input class="form-control username" type="text" placeholder="Username" id="username" />
  </div>

  <div>
    <label for="Password">Password</label>
    <input class="form-control password" type="password" placeholder="Password" id="password" />
  </div>

  <div style="text-align:center;">
    <button id="login">Login</button>
  </div>
</div>

话虽如此,您可以简化此示例以仅使用find()而不是显式遍历所有同级div:

$('#login').click(function() {
  var $username = $(this).parent('div').siblings('div:has(input)').find('.username');      
  console.log($username.length);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div>
    <label for="username">Username</label>
    <input class="form-control username" type="text" placeholder="Username" id="username" />
  </div>

  <div>
    <label for="Password">Password</label>
    <input class="form-control password" type="password" placeholder="Password" id="password" />
  </div>

  <div style="text-align:center;">
    <button id="login">Login</button>
  </div>
</div>

更简单的方法是使用登录submit中的form事件,然后在其中使用find() .username中的事件:

$('#yourLoginForm').on('submit', function() {
  var $username = $(this).find('.username');
});