【问题标题】:How to properly use jquery val() to match CSS selectors如何正确使用 jquery val() 来匹配 CSS 选择器
【发布时间】:2018-03-01 15:02:56
【问题描述】:

我有一个带有一些输入的表单和一个附加到它们的 CSS,它使用属性值选择器根据值更改输入的背景颜色。

例子

<!DOCTYPE html>
<html>
  <head><style>
    input[value="foo"] { background-color: red; }
  </style></head>
  <body>
    <form>
     <input value="foo" />
     <button/>
    </form>
  </body>
</html>

如果我在加载时使用foo 作为值,如代码中所示,加载时该字段将是红色的,但如果我更改它,它将保持红色。如果我将输入的值更改为foo,同样的事情,它不会改变背景颜色。

如果我在 jQuery 中使用 .val() 也是如此。显然,在这些情况下,“动态”值发生了变化,而 CSS 指的是“静态”值。

$('button').on('click', function(ev) {
  ev.preventDefault();
  $('input[value="foo"]').val('bar');
  // $('input[value="bar"]').val('baz'); // nothing is found
});

我希望这段代码将字段从foo 更改为bar,然后将bar 更改为baz,但在第二个选择器中找不到该字段。

如果我使用 attr 方法,一切似乎都有效,但在 jQuery 文档(以及这里的许多答案)中,val 是可行的方法。

为什么会这样,我为什么要使用val()

【问题讨论】:

  • This 应该会有所帮助。基本上,你已经尝试过使用.filter.attr
  • 在我的回答中,我试图解释你的基本误解。
  • 实际问题的细节是什么?颜色变化是否完全基于值是否已从其原始属性更新?
  • @doodlemeister 实际问题是我想在空输入字段附近添加一个 :pseudo 元素,但由于值选择器的工作方式,我遇到了问题。

标签: javascript jquery html css


【解决方案1】:

“为什么会这样……”

这是一个属性选择器,当您更新.value 属性时,该属性不会更改,因此您需要显式更改该属性。

$('button').on('click', function(ev) {
  ev.preventDefault();
  $('input[value="foo"]').val('bar').attr("value", "bar");
  $('input[value="bar"]').val('baz');
});
input[value="foo"] {
  background-color: red;
}

input[value="bar"] {
  background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>

<form>
  <input value="foo" />
  <button/>
</form>

但是当用户更改值时,这将不起作用,除非您连接 .on("input"... 处理程序以使属性与属性保持同步。

$("input").on("input", function() {
  this.setAttribute("value", this.value);
});
input[value="foo"] {
  background-color: red;
}

input[value="bar"] {
  background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>

<form>
  Change the value to "bar"
  <input value="foo" />
</form>

“……我为什么要使用val()?”

只需通过属性获取和设置值,同时保留原始值。

需要同步它们并不常见。按值选择 DOM 有点像按文本内容选择 DOM。它只是不是经常需要,有时有更好的方法来解决问题。

【讨论】:

  • 这就是为什么 OP 甚至不应该尝试这样做。他的问题是理解 HTML 属性值和 DOM API 输入元素值属性之间的区别。这就是答案所阐述的内容。
  • 非常感谢您对选择器的解释。
  • &lt;button/&gt; 是不允许的。可能有内容的元素不能自动关闭。
【解决方案2】:
input[value="foo"]

选择具有显式属性 value 等于fooinput 元素。

input 元素中键入foo不会创建这样的属性,也不会在input 上键入任何其他属性删除具有属性value="foo"

jQuery 的 val() 是读取值的正确方法,问题是您的选择器 $('input[value="bar"]') 找不到任何东西,因为设置 input 的值 property 不会更改/添加属性

【讨论】:

  • 谢谢,感谢您为解释差异所做的努力。现在我想知道在这种情况下 jQuery prop('value') 怎么样?是否等同于val()
  • 阅读api.jquery.com/prop "Attributes vs Properties" 还要注意HTML属性value只有一个目的——通过HTML预先设置值。
  • 我做了,但它主要谈论布尔属性和默认属性,IMO 并没有很好地解释差异。
  • 区别在于prop用于属性,而attr用于属性。区别还不清楚吗?因为想要访问输入的当前值是如此普遍的需求,并且主要是因为 jQuery 在 1.6 之前没有 prop 方法,所以 jQuery 提供了 prop 的专用变体,称为 val。它从未被删除,因为这会破坏很多代码。
【解决方案3】:

我希望这个 sn-p 解释得很好

$input = $('input')

console.log('val:', $input.val())
console.log('attr:', $input.attr('value'))

// attr will get the attribute from html not the *dynamic* value has been set
$input.val('bar')
console.log('val:', $input.val())
console.log('attr:', $input.attr('value'))

// same here when you use val you change the property value of input not the attribute
$input.attr('value', 'bazzz')

console.log('val:', $input.val())
console.log('attr:', $input.attr('value'))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input value="foo" />

【讨论】:

    【解决方案4】:

    对于任何了解 HTML 技术的人来说,我当然错了,但根据我自己的直觉,我一直认为 HTML 文件中的任何内容都是 属性 以及之后的任何值作为 properties (我猜你可以称它们为运行时值)。如果你想更深入地了解,你需要谷歌它,因为我只是没有这样的知识:) 请记住,我在这里的总结过于简单了。

    你可以做以下实验。在 Chrome 上,如果您按 Ctrl+J(对不起,我不知道其他浏览器的组合是什么),您可以弹出打开 javascript 控制台。在那里,输入

    $("input[value=foo]").val("bar");
    

    然后转到 DOM 资源管理器并注意值 attribute 没有改变。为了改变它,你需要使用函数

    $("input[value=foo]").attr("value","bar");
    

    然后你就可以实现你想要的。

    【讨论】:

    • 虽然您的直觉是可以理解的,但不幸的是它并不那么简单。有些属性实际上映射到它们对应的属性,所以当属性发生变化时,属性也会发生变化。碰巧value 并非如此。
    猜你喜欢
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 2020-10-28
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多