是否有CSS选择器来检测输入是否选择了文本文件?

时间:2010-11-13 22:19:26

标签: css css-selectors

我正在尝试输入一些文件,只有在前一个文件输入已填满的情况下才显示它们。这也可以使用css 3.

3 个答案:

答案 0 :(得分:6)

为了扩展易江的评论,针对“价值”属性的选择者不会注意到“价值”属性的变化。 “value”属性绑定到"defaultValue" property,而"value" property未绑定到任何属性(感谢porneL指出这一点)。

请注意,与“checked”属性和“defaultChecked”以及“checked”属性存在类似的关系;如果使用属性选择器[checked]而不是伪类:checked,则当复选框的状态发生更改时,您将看不到样式更改。与“已检查”系列不同,“值”没有您可以使用的相应伪类。

尝试以下测试页:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Dynamic attribute selectors</title>
    <style type="text/css">
     input:not([value]), div:not([value]) {
       background-color: #F88;
     }

     input[value], div[value] {
       border: 5px solid #8F8;
     }
     input[value=""], div[value=""] {
       border: 5px solid #F8F;
     }

     input:not([value=""]), div:not([value=""]) {
       color: blue;
       border-style: dashed;
     }

     *.big {
         font-size: 200%;
     }
    </style>
    <script>
      function getElt() {
          var id=prompt("Enter ID of element", "d1");
          if (id) {
              return document.getElementById(id);
          } else {
              return {className: ''};
          }
      }

      function embiggen() {
          getElt().className="big";
          return false;
      }

      function smallify() {
          getElt().className="";
          return false;
      }
    </script>
  </head>

  <body>
    <form method="post"  enctype="multipart/form-data"> 
      <div id="d1">no value</div>
      <div id="d2" value="">empty value</div>
      <div id="d3" value="some">some value</div>
      <p><label for="foo">foo:</label> <input name="foo" id="foo" /></p> 
      <p><label for="bam">bam:</label> <input name="bam" id="bam" value="bug-AWWK" /></p> 
      <p><label for="file">File to upload:</label> <input type="file" name="file" id="file" onchange="setValueAttr(this)"/></p>
      <input type="button" value="Embiggen" onclick="return embiggen()" />
      <input type="button" value="Smallify" onclick="return smallify()" />
    </body>
</html>

更改任何内容的值和样式不会改变。更改任何类的类,样式将更改。如果添加以下JS函数并将其绑定到输入上的change事件,则背景样式将更改。

      function bindValue(elt) {
          var oldVal=elt.getAttribute('value');
          elt.setAttribute('value', elt.value);
          var newVal=elt.getAttribute('value');
          if (oldVal != newVal) {
              alert('Had to change value from "'+oldVal+'" to "'+newVal+'"');
          }
      }

这会将“value”属性绑定到“value”属性,因此用户输入对前者的更新将传播到后者(以编程方式设置“value”属性不会导致更改事件。)

在检查文件输入的JS属性之前和之后(通过使用以下脚本),唯一具有明显变化的是“值”。由此,我怀疑是否有任何其他HTML属性发生了变化,因此可以在属性选择器中使用。

<script>
  var file = {blank: {}, diff: {}};
  var fInput = document.getElementById('file');
  for (p in fInput) {
    try {
      file.blank[p] = fInput[p];
    } catch (err) {
      file.blank[p] = "Error: setting '"+p+"' resulted in '"+err+"'";          
    }
  }

  function fileDiff() {
    for (p in fInput) {
      try {
        if (file.blank[p] != fInput[p]) {
          file.diff[p] = {orig: file.blank[p], now: fInput[p]};
        }
      } catch (err) {
        //file.diff[p] = "Error: accessing '"+p+"' resulted in '"+err+"'";          
      }
    }

  }

  if (fInput.addEventListener) {
    fInput.addEventListener('change', fileDiff, false);
  } else if (fInput.attachEvent) {
    fInput.attachEvent('onchange', fileDiff);
  } else {
    fInput.onchange = fileDiff;
  }
</script>

你可以使用指向不存在的片段和:visited伪类的链接来破解某些东西,但它非常令人震惊。

<style>
 a input {
   display: none;
 }
 :not(a) + a input,
 a:visited + a input
 {
   display: block /* or "inline" */ ;
 }

</style>
...
<a href="#asuhacrpbt"><input type="file" ... /></a>
<a href="#cmupbnhhpw"><input type="file" ... /></a>
<a href="#mcltahcrlh"><input type="file" ... /></a>

每次加载页面时,您都需要为链接生成未访问的目标。由于你必须在服务器方面做这件事,你不可能完全确定地做到这一点,尽管你可以将生成以前访问过的目标的概率任意接近0。它也不适用于所有浏览器,例如苹果浏览器。我怀疑这是由于来自CSS2CSS3的以下内容:

  

注意:样式表作者可以滥用:link和:visited伪类来确定用户未经用户同意访问过哪些网站。

     因此,UA可能会将所有链接视为未访问的链接,或实施其他措施以保护用户的隐私,同时以不同方式呈现访问和未访问的链接。

你可能能够在其他元素上使用其他选择器一起破解某些东西,但我怀疑这不能干净利落。

答案 1 :(得分:6)

值得千言万语的例子:Display X input, one at a time

这个想法很简单,如果输入设置为空,则无效。从那里,您所要做的就是根据需要设置所有输入并使用:invalid伪类。也应该与标签一起使用。

答案 2 :(得分:0)

要选择空白字段,您可以尝试

input[type=file][value=""] {
    background-color: red;
}

我在jsfiddle上测试过它。至少,我需要在输入标签上定义一个空值属性才能使其工作

<input type="file" id="test" value="">

在您的示例中使用'+'运算符将匹配两个单独的文件输入,一个接着一个。它不会检查您想要的同一标记的两个属性。