是否可以在多个<模板>片段上使用重复的 ID?

Can I use duplicate IDs on multiple <template> fragments?

提问人:stoic little 提问时间:8/10/2020 最后编辑:Alohcistoic little 更新时间:10/28/2020 访问量:628

问:

为什么 HTML5 验证在具有重复的元素 ID 但在不同的 .我计划一次只使用一个模板,这样实际的 DOM ID 就不会被复制。<template>

像这样:

<template id="companyAccount">
   <li><label>Company: <input type="text" id="account_name"></label></li>
   <li><label>Street: <input id="account_street" ...
   ...
</template>
<template id="residentialAccount">
   <li><label>Name: <input type="text" id="account_name"></label></li>
   <li><label>Street: <input id="account_street" ...
   ...
</template>
<script>
...
let template = $(isResidential ? '#residentialAccount' : '#companyAccount').get(0).content;
$('#account_info').empty().append(template.cloneNode(true));
</script>
HTML DOM xhtml w3c验证

评论

0赞 TJBlackman 8/10/2020
发布示例代码。你是如何“一次只显示一个”的?
0赞 stoic little 8/10/2020
@TJBlackman - 我添加了一个示例。
0赞 TJBlackman 8/11/2020
ID 必须是全局唯一的,因此当它们存在时,它们永远只有一个。看起来同一个 ID 可能会在 HTML 文件上出现不止一次,也许并非总是如此,但即使只是一秒钟,它也会失败。如果必须使用相同的 ID,则必须 100% 确保在添加另一个 ID 之前完全删除一个 ID。但只需使用类或数据属性即可解决问题。
0赞 Alohci 8/12/2020
据我所知,每个模板的内容都进入一个单独的文档,因此每个 id 在其文档中都是唯一的,不应该是验证错误。但坦率地说,唯一能够回答这个问题的人是 sideshowbarker,所以你不妨把它作为一个问题在验证器上提出来。

答:

0赞 John 10/28/2020 #1

正如 TJBlackman 所提到的,每个属性都必须是唯一的。但是,在使用代码时,由您来确定导入的代码是否包含重复的 .此外,我几乎已经停止使用验证器,因为它们没有得到很好的维护(而且 W3C 的 CSS 验证器很糟糕)和控制台、正确的错误处理和使用 HTML5 的 XML 解析器将告诉你几乎所有你需要知道的东西。valueidid

您有几种选择。您可以使用(不要错误地使用 camelCasing,因为这最终会让你与标准机构直接冲突)并通过以下方式检测属性:data-account="residential"document.querySelectorAll

function $(o)
{
 var a = true;

 try {document.querySelectorAll(o);}
 catch(err) {a = false; console.log('Error: "'+o+'" is not a valid CSS selector.'); sound.notice();}

 return (a && document.querySelectorAll && document.querySelectorAll(o)) ? document.querySelectorAll(o) : false;
}

用法: 和 .$('[data-account="residential"]')[0].length$('[data-account="residential"]')[0].value

或者,您可以像我一样使用我的平台进行操作,该平台将东西紧密集成在一起,尽管这是我使用的功能,您可能会决定为您的特定目的进行瘦身。您可以使用并逐字逐句地检查要扫描的每个元素,以测试。在将 XML 导入到我的平台上的 DOM 之前,会使用此代码:document.createTreeWalkerwalker.currentNode.hasAttribute('id')document.getElementById

/******** part of larger ajax() function ********/

if (xhr.readyState == 4 && xhr.status != 204)
{}

//This code occurs within the above condition.
var r = jax_id_duplication_prevention(xhr.responseXML,param_id_container_pos,id_container);

if (r)
{
 if (param_id_container_pos=='after') {id_container.parentNode.insertBefore(xml.getElementsByTagName('*')[0],id_container.nextSibling);}
 else if (param_id_container_pos=='before') {id_container.parentNode.insertBefore(document.importNode(xml.getElementsByTagName('*')[0],true),id_container);}
 else if (param_id_container_pos=='first')
 {
  if (id_container.childNodes.length > 0) {id_container.insertBefore(document.importNode(xml.getElementsByTagName('*')[0],true),id_container.firstChild);}
  else {id_container.appendChild(document.importNode(xml.getElementsByTagName('*')[0],true));}
 }
 else if (param_id_container_pos=='inside') {id_container.appendChild(document.importNode(xml.getElementsByTagName('*')[0],true));}
 else if (param_id_container_pos=='replace') {id_container.parentNode.replaceChild(document.importNode(xml.getElementsByTagName('*')[0],true),id_container);}
 else if (param_id_container_pos=='fragment')
 {
  if (option.fragment) {delete option.fragment;}
  option.fragment = document.importNode(new DOMParser().parseFromString(xhr.responseText,'application/xml').childNodes[0],true);
  if (id_container && typeof id_container == 'function') {id_container();}
 }
 else {alert('Error: unknown position to import data to: '+id_container_pos);}
}
/******** part of larger ajax() function ********/

function ajax_id_duplication_prevention(xml,param_id_container_pos,id_container)
{
 var re = true;
 if (typeof id_container == 'string' && id_container.length > 0 && id_(id_container)) {id_container = id_(id_container);}

 if (typeof option.id_fade == 'string' && option.id_fade.length > 0 && id_(option.id_fade)) {element_del(option.id_fade); option.id_fade = '';}

 if (typeof xml.firstChild.hasAttribute == 'function')
 {
  if (xml.firstChild.hasAttribute('id') && xml.firstChild.getAttribute('id').length > 0 && id_(xml.firstChild.getAttribute('id')) && id_(xml.firstChild.id).parentNode.id=='liquid') {change(xml.firstChild.id,'fade');}

  if (xml.firstChild.hasAttribute('id') && xml.firstChild.getAttribute('id').length > 0 && id_(xml.firstChild.id) && !id_(xml.firstChild.id).parentNode.id=='liquid') {re = false;}
  else if (typeof document.createTreeWalker=='function')
  {
   var idz = [];
   try
   {
    var walker = document.createTreeWalker(xml,NodeFilter.SHOW_ELEMENT,null,false);

    while (walker.nextNode())
    {
     if (walker.currentNode.hasAttribute('id') && walker.currentNode.getAttribute('id').length > 0)
     {
      if (walker.currentNode.id==undefined && walker.currentNode.nodeName.toLowerCase()=='parsererror') {console.log('Error: a parser error was detected.');}
      else if (walker.currentNode.id==undefined) {alert('walker.currentNode.nodeName = '+walker.currentNode.nodeName+'\n\n'+document.serializeToString(xml));}
      else
      {
       for (var i = 0; i<id_('liquid').childNodes.length; i++)
       {
        if (id_('liquid').childNodes[i].nodeType==1 && id_(walker.currentNode.id) && is_node_parent(walker.currentNode.id,id_('liquid').childNodes[i]) && (param_id_container_pos!='replace' || walker.currentNode.id!=id_container.id))
        {
         if (param_id_container_pos != 'replace' && id_container != walker.currentNode.id) {element_del(id_('liquid').childNodes[i]);}//If changing operator test: ajax('get','?ajax=1&web3_url=/'+url_section()+'/'+url_page(),'replace',push_current_id());
        }
       }

       var n = id_(walker.currentNode.id);
       if (in_array(walker.currentNode.id,idz))
       {
        var fd = new FormData();
        fd.append('ajax','error_xml');
        fd.append('post_error','Duplicate id <code>'+walker.currentNode.id+'</code>.');
        fd.append('post_url',url_window().split(url_base())[1].split('?')[0]);
        fd.append('post_xml',new XMLSerializer().serializeToString(xml));
        if (fd) {ajax('post',path+'/themes/',fd);}

        modal.alert('Error: can not import XML, the id \''+walker.currentNode.id+'\' was detected twice in the layer being imported. Duplicated ID\'s break expected functionality and are illegal. While the XML content was not imported it is still possible that the related request was successful. It is possible to override this problem by simply doing a full request (press the Go button in your browser\'s graphic user interface) however if the id is referenced programmatically the website may exhibit unusual behavior.');
        break;
        setTimeout(function()
        {
         history.back();
         push_reload();
         console.log('Developer: duplicate id '+walker.currentNode.id+' was encounterted.');
         if (status >= 9) {modal.xml('Duplicate ID Error', '%3Cp%3EError%3A%20the%20id%20%3Ccode%3E'+walker.currentNode.id+'%3C%2Fcode%3E%20occurred%20twice%20and%20therefore%20the%20page%20can%20not%20be%20viewed.%3C%2Fp%3E%3Cp%3EFor%20debugging%20and%20fixing%20purposes%20you%20should%20consider%20opening%20the%20URL%20in%20a%20new%20tab.%3C%2Fp%3E%3Cdiv%20class%3D%22center%20margin%22%3E%3Cinput%20onclick%3D%22modal.close()%3B%22%20tabindex%3D%223%22%20type%3D%22button%22%20value%3D%22Close%22%20%2F%3E%3C%2Fdiv%3E');}
         else {modal.xml('Duplicate ID Error', '%3Cp%3EError%3A%20the%20id%20%3Ccode%3E'+walker.currentNode.id+'%3C%2Fcode%3E%20occurred%20twice%20and%20therefore%20the%20page%20can%20not%20be%20viewed.%3C%2Fp%3E%3Cdiv%20class%3D%22center%20margin%22%3E%3Cinput%20onclick%3D%22modal.close()%3B%22%20tabindex%3D%223%22%20type%3D%22button%22%20value%3D%22Close%22%20%2F%3E%3C%2Fdiv%3E');}
         re = false;
        },4000);
       }
       else {idz.push(walker.currentNode.id);}
      }

      if (id_(walker.currentNode.id) && (param_id_container_pos!='replace' && walker.currentNode.id!=id_container.id && !is_node_parent(walker.currentNode.id,id_container)))
      {//ajax replace (carousel loader) complications if changed.
       re = false;
       modal.alert('Error: unable to import page, the id \''+walker.currentNode.id+'\' already exists in the DOM.');
       break;
      }
     }
    }
   }
   catch (err) {}//IE9
  }
 }

 return re;
}

无论您如何解决该问题,它都不是由标准机构解决的问题,必须由开发人员明确处理。未能处理重复的属性/值将导致在某些时候选择了错误的元素,随着时间的推移,这可能会悄悄地积累出多年来可能没有人注意到的受损/畸形数据,因此很容易阻碍甚至彻底破坏受其影响的任何业务关系。祝你好运!id