我如何让jQuery选择带有的元素。(时段)的ID?


172

给定以下类和控制器操作方法:

public School
{
  public Int32 ID { get; set; }
  publig String Name { get; set; }
  public Address Address { get; set; }
}

public class Address
{
  public string Street1 { get; set; }
  public string City { get; set; }
  public String ZipCode { get; set; }
  public String State { get; set; }
  public String Country { get; set; }
}

[Authorize(Roles = "SchoolEditor")]
[AcceptVerbs(HttpVerbs.Post)]
public SchoolResponse Edit(Int32 id, FormCollection form)
{
  School school = GetSchoolFromRepository(id);

  UpdateModel(school, form);

  return new SchoolResponse() { School = school };
}

以及以下形式:

<form method="post">
  School: <%= Html.TextBox("Name") %><br />
  Street: <%= Html.TextBox("Address.Street") %><br />
  City:  <%= Html.TextBox("Address.City") %><br />
  Zip Code: <%= Html.TextBox("Address.ZipCode") %><br />
  Sate: <select id="Address.State"></select><br />
  Country: <select id="Address.Country"></select><br />
</form>

我可以同时更新School实例和School的Address成员。这真是太好了!谢谢ASP.NET MVC团队!

但是,如何使用jQuery选择下拉列表,以便可以预先填写呢?我意识到我可以在服务器端进行操作,但是页面上还会有其他影响列表的动态元素。

以下是我到目前为止所拥有的,并且由于选择器似乎与ID不匹配而无法正常工作:

$(function() {
  $.getJSON("/Location/GetCountryList", null, function(data) {
    $("#Address.Country").fillSelect(data);
  });
  $("#Address.Country").change(function() {
    $.getJSON("/Location/GetRegionsForCountry", { country: $(this).val() }, function(data) {
      $("#Address.State").fillSelect(data);
    });
  });
});

Answers:


293

来自Google网上论坛

在每个特殊字符之前使用两个反斜杠。

jQuery选择器中的反斜杠转义下一个字符。但是您需要两个,因为反斜杠也是JavaScript字符串的转义字符。第一个反斜杠转义第二个反斜杠,为您的字符串提供一个实际的反斜杠-然后转义jQuery的下一个字符。

所以,我想你在看

$(function() {
  $.getJSON("/Location/GetCountryList", null, function(data) {
    $("#Address\\.Country").fillSelect(data);
  });
  $("#Address\\.Country").change(function() {
    $.getJSON("/Location/GetRegionsForCountry", { country: $(this).val() }, function(data) {
      $("#Address\\.State").fillSelect(data);
    });
  });
});

还请查看如何通过具有CSS表示法中使用的字符的ID选择元素?在jQuery FAQ上。


4
我不知道要求开发人员执行此操作的合理性是什么,似乎jQuery中的一组简单启发式方法就可以解决此问题,因为ID中没有句点是什么问题……
Jason Bunting

5
如果您不必转义,您将如何查询具有ID地址和类State的元素(允许,如果您知道该ID,则无需通过指定该类来添加太多内容,但它仍然有效,我想认为)?
bdukes

12
因此,在CSS本身中,您也必须在ID中转义一个点。jQuery所做的只是要求您遵循CSS规定的规则。
bdukes

6
您也可以按名称而不是ID进行选择。例如,$('[[name =“ Address.Country”]')
Funka

25

如果id包含空格,则不能使用jQuery id选择器。使用属性选择器:

$('[id=foo bar]').show();

如果可能,还指定元素类型:

$('div[id=foo bar]').show();

与使用转义字符相比,我更喜欢这样做。...显然,最好的解决方法是不要在id中使用句点。
GordonB

id不允许使用空格,即使HTML5更自由地接受字符也不允许使用空格。stackoverflow.com/questions/70579/…–
杰·布兰查德

的确如此,但是是否允许使用对可怜的树液无关紧要,后者一直在为90年代后期部署的写得不好的Web应用程序添加窗口装饰。
Elliot Nelson

4
为了工作,必须有一些引号:`$(“ div [id ='” + variable +“']”))`或`$(“ div [id ='foo bar']”))`
olga 2013年

正如@olga所说,答案不再合法。具体来说,您会收到一条错误消息“未捕获的错误:语法错误,无法识别的表达式:div [id = foo bar]”
James Moore

13

为Jquery转义:

function escapeSelector(s){
    return s.replace( /(:|\.|\[|\])/g, "\\$1" );
}

用法示例:

e.find('option[value='+escapeSelector(val)+']')

更多信息在这里


3
根据jQuery文档的解决方案仅添加一个“ \”(斜杠)。alert(escapeSelector(“ some.id”)); 将输出为some \ .id。所以我想替换正则表达式应该是s.replace(/(:|\.|[|])/g,“ \\\\ $ 1”);
2015年

我有同样的问题,为什么其他人都看不到呢?
TruthOf42

9

刚刚发布的ASP.NET MVC的发布候选版本解决了此问题,现在将ID属性的下划线替换为下划线。

<%= Html.TextBox("Person.FirstName") %>

呈现给

<input type="text" name="Person.FirstName" id="Person_FirstName" />

有关更多信息,请参阅从第14页开始的发行说明。


1
我看不到这是什么“修复”-ASP.NET MVC为什么必须将ID更改为jQuery需要的东西?我认为jQuery是问题所在,而不是使用。在ID中。
詹森·邦廷

7
该点在CSS中用于识别/组合类具有特殊含义,这就是为什么将其包含在ID中很麻烦。“问题”与jQuery无关。
Funka

4

jQuery Selectors文档中对此进行了说明:

要将任何元字符(例如 !"#$%&'()*+,./:;<=>?@[\]^`{|}~)用作名称的文字部分,必须使用两个反斜杠对它进行转义:\\。例如,带有的元素 id="foo.bar"可以使用选择器$("#foo\\.bar")

总之,前缀.\\如下:

$("#Address\\.Country")

为什么.我的ID不起作用?

问题是.具有特殊的意义,下面的字符串被解释为类选择器。所以$('#Address.Country')会匹配<div id="Address" class="Country">

当转义为时\\.,该点将被视为普通文本,没有特殊意义,与您想要的ID相匹配<div id="Address.Country">

这适用于所有!"#$%&'()*+,./:;<=>?@[\]^`{|}~在jQuery中作为选择器具有特殊意义的字符。只需\\将它们视为普通文本即可。

为什么是2 \\

如bdukes答案中所述,有一个原因我们需要2个\字符。\将在JavaScript中转义以下字符。Se当JavaScript解释字符串时"#Address\.Country",它将会看到并\解释为随意接受以下字符并将字符串作为参数传入时删除$()。这意味着jQuery仍将字符串视为"#Address.Country"

那就是第二个\出现的地方。第一个告诉JavaScript将第二个解释为文字(非特殊)字符。这意味着jQuery将看到第二个. 字符,并理解后面的 字符是文字​​字符。

!也许我们可以想象一下。

//    Javascript, the following \ is not special.
//         | 
//         |
//         v    
$("#Address\\.Country");
//          ^ 
//          |
//          |
//      jQuery, the following . is not special.

3

使用两个反斜杠就可以了。但是,如果您使用的是动态名称(即变量名称),则需要替换字符。

如果您不想更改变量名称,则可以执行以下操作:

var variable="namewith.andother";    
var jqueryObj = $(document.getElementById(variable));

并且比起您的jquery对象。


0

仅提供其他信息:检查此ASP.NET MVC问题#2403

在问题解决之前,我使用自己的扩展方法,例如Html.TextBoxFixed等,该扩展方法只是在id属性(而不是name属性)中用下划线替换点,以便您使用$(“#Address_Street”)之类的jquery但是在服务器上,它就像Address.Street。

示例代码如下:

public static string TextBoxFixed(this HtmlHelper html, string name, string value)
{
    return html.TextBox(name, value, GetIdAttributeObject(name));
}

public static string TextBoxFixed(this HtmlHelper html, string name, string value, object htmlAttributes)
{
    return html.TextBox(name, value, GetIdAttributeObject(name, htmlAttributes));
}

private static IDictionary<string, object> GetIdAttributeObject(string name)
{
    Dictionary<string, object> list = new Dictionary<string, object>(1);
    list["id"] = name.Replace('.', '_');
    return list;
}

private static IDictionary<string, object> GetIdAttributeObject(string name, object baseObject)
{
    Dictionary<string, object> list = new Dictionary<string, object>();
    list.LoadFrom(baseObject);
    list["id"] = name.Replace('.', '_');
    return list;
}

1
来自上述问题:“ UpdateModel()使用点,因为这是表单元素的输入方式。表单元素使用点,因为这是在HTML帮助器调用中指定的方式。HTML帮助器使用点是因为这样最后,ViewData.Eval()使用一个点,因为这是在主要的.NET Framework语言中分隔对象及其属性的方式。整个链条的流程。”
Simon_Weaver 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.