为什么querySelectorAll在文本类型上会错过具有隐式文本类型的输入?

时间:2018-05-24 15:16:05

标签: javascript html css-selectors

我有一个普通的<input>元素。

我希望document.querySelectorAll('input[type="text"]')能够检索(至少)该输入,因为the default input type is text

querySelectorAll除非我明确设置type="text"

,否则不会返回该输入

我有两个问题:

  1. 为什么querySelectorAll会忽略带有隐式type="text"的输入?
  2. 是否有一个查询来定位隐式类型为text的输入,该输入排除了所有类型不是text的输入?
  3. 以下是一个说明问题的示例文档:

    &#13;
    &#13;
    var output = document.getElementById('output');
    
    var textInputs = document.querySelectorAll('input[type="text"]');
    
    output.innerText = 'input[type="text"] - ' + textInputs.length + ' elements';
    
    var inputs = document.querySelectorAll('input');
    
    output.innerText += '\ninput - ' + inputs.length + ' elements';
    
    output.innerText += '\n\nFirst input type: ' + inputs[0].type;
    &#13;
    #output {
      font-family: monospace;
    }
    &#13;
    <form>
      <input>
      <input type="text">
      <div id="output"></div>
    </form>
    &#13;
    &#13;
    &#13;

    这是我的浏览器(Chrome)中的JavaScript输出:

    input[type="text"] - 1 elements
    input - 2 elements
    
    First input type: text
    

3 个答案:

答案 0 :(得分:2)

属性选择器不会将无效或缺失值默认值考虑在内。只有在标记中明确指定了属性时,它们才会匹配。

您仍然可以使用input:not([type])考虑缺失值默认值,因为没有input属性的type元素可以通过其缺失值默认保证为文本输入(除非由脚本突变)。

var output = document.getElementById('output');

var textInputs = document.querySelectorAll('input:not([type]), input[type=text]');

output.innerText = 'input[type="text"] - ' + textInputs.length + ' elements';

var inputs = document.querySelectorAll('input');

output.innerText += '\ninput - ' + inputs.length + ' elements';

output.innerText += '\n\nFirst input type: ' + inputs[0].type;
#output { 
  font-family: monospace; 
}
<form>
    <input>
    <input type="text">
    <input type="number">
    <div id="output"></div>
</form>

答案 1 :(得分:1)

  

为什么querySelectorAll会忽略带有隐式类型的输入=&#34; text&#34;?

由于它是隐式的,因此元素上不存在该属性,因此属性选择器不匹配。

  

是否有一个查询来定位一个输入,其隐式类型是排除所有类型不是文本的输入的文本?

匹配完全没有类型属性的元素。

&#13;
&#13;
console.log(
  document.querySelectorAll("input[type=text], input:not([type])").length,
  "matching elements"
);
&#13;
input[type=text],
input:not([type]) {
  background: blue;
}
&#13;
<ol>
  <li><input></li>
  <li><input type="text"></li>
  <li><input type="number"></li>
</ol>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

以下是一些答案:

  1. 正如许多人已经提到的那样,querySelectorAll需要明确的类型来匹配它。

  2. 您可能希望使用代码段中的代码来过滤&#34;过滤&#34; querySelectorAll

  3. 的结果

    第三个回答:
    使用.setAttribute("type", "text")在没有它的元素上显式添加属性

    &#13;
    &#13;
    // Add 'type="text"' on the ones which don't have it
    document.querySelectorAll('input:not([type])').forEach(function(elm){
      elm.setAttribute("type", "text");
    });
    
    // Output
    var inputs = document.querySelectorAll('input[type="text"]');
    document.getElementById('output').innerText += 'input[type="text"] - ' + inputs.length + ' elements';
    &#13;
    <form><!-- Added other input types -->
      <input>
      <input type="text">
      <input type="number">
      <input type="date">
      <div id="output"></div>
      <script>
      </script>
    </form>
    &#13;
    &#13;
    &#13;

    ⋅ ⋅ ⋅

    第二个答案(其他人更快):
    input:not([type])

    中添加querySelectorAll

    &#13;
    &#13;
    var output = document.getElementById('output');
    var inputs = document.querySelectorAll('input[type="text"], input:not([type])');
    
    output.innerText += 'input[type="text"] - ' + inputs.length + ' elements';
    &#13;
    <form><!-- Added other input types -->
      <input>
      <input type="text">
      <input type="number">
      <input type="date">
      <div id="output"></div>
      <script>
      </script>
    </form>
    &#13;
    &#13;
    &#13;

    ⋅ ⋅ ⋅

    第一个答案(不值得):
    使用循环检查querySelectorAll

    返回的每个元素

    &#13;
    &#13;
    // Variables
    var output = document.getElementById('output');
    var inputs = document.querySelectorAll('input');
    var textInputs = [],
      j = 0;
    
    // Loop
    for (i = 0; i < inputs.length; i++) {
      if (inputs[i].type == 'text') {
        textInputs[j] = inputs[i];
        j++
      }
    }
    
    // Output
    output.innerText = 'input[type="text"] - ' + textInputs.length + ' elements';
    &#13;
    <form><!-- Added other input types -->
      <input>
      <input type="text">
      <input type="number">
      <input type="date">
      <div id="output"></div>
      <script>
      </script>
    </form>
    &#13;
    &#13;
    &#13;

    希望它有所帮助。