使用类后缀整数的参考ID

时间:2019-06-12 08:11:10

标签: jquery jquery-selectors

情况:

有很多复选框,这只是树的一小部分:

<li class="main">
    <input type="checkbox" id="cat_6" class="parent_cat_0" name="local[]">
    <label class="strong" for="cat_6">Stellenbeschreibungen</label>
    <ul>
        <li class="main">
            <input type="checkbox" id="doc_31" class="parent_cat_6" name="local[]">
            <label for="doc_31">Stellenbeschreibung Marketing/Vertrieb</label>
        </li>
    </ul>
</li>

我想为具有“ parent_cat_6”类的此复选框的父级选择器

所以最终的选择器应该是:

let parent = $('#cat_6');

但是我不知道如何从选中的复选框类中删除“ parent_”。

child has class="parent_cat_6"
parent has id="cat_6"

我需要使用正则表达式来为父级选择器吗?

更新: 这有效:

selected.attr('class').split(' ').slice(-1)[0].substr(7);

但这很丑陋,欢迎任何改进!

1 个答案:

答案 0 :(得分:0)

当必须处理JavaScript中的引用时,

带后缀或前缀的ClassName并不是最佳选择。

疯狂的选择器

仅针对此类后缀类-选择器变得复杂:

[class^="parent_cat_"], [class*=" parent_cat_"]

在这种情况下,您最好使用两个类,一个对所有元素都通用,而特定的一个是class="cat_checkbox parent_cat_42"。这样,选择器就变得像

一样简单
.cat_checkbox   // BETTER - Common class for all checkboxes

要提取后缀Integer太多的工作

问题是, className 可以容纳许多名称,要找到所需的名称可能很棘手。
如何从42中提取class="foo bar fooBar parent_cat_42 bla_bli_40"

  • 阅读整个classList
  • 找到与该格式parent_cat_\d+匹配的那个
  • 获取索引
  • 提取
  • 获取数字
  • 最后将其转换为ID #cat_[ID]

const findIndex_parent_cat = klass => /^parent_cat_\d+$/.test(klass);
const findNum_parent_cat = klass => klass.replace(/\D+/, '');


$('[class^="parent_cat_"], [class*=" parent_cat_"]').on('change', function() {
  const klasses = $(this).attr('class');
  const ID = klasses.match(/(?:^|\s)parent_cat_(\d+)(?:$|\s)/)[1];
  const cat_ID = `#cat_${ID}`;
  console.log(`ID: ${cat_ID}`);
  $(cat_ID).prop({checked: this.checked});
});
<ul>
  <li class="main">
    <input type="checkbox" id="cat_6" class="something parent_cat_0 bla" name="local[]">
    <label class="strong" for="cat_6">Stellenbeschreibungen</label>
    <ul>
      <li class="main">
        <input type="checkbox" id="doc_31" class="blue red inp parent_cat_6 foo bar" name="local[]">
        <label for="doc_31">Stellenbeschreibung Marketing/Vertrieb</label>
      </li>
    </ul>
  </li>
</ul>

<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>

使用正则表达式获取类后缀Integer

或者可以通过使用正则表达式(?:^|\s)parent_cat_(\d+)(?:$|\s)来完成:

const findIndex_parent_cat = klass => /^parent_cat_\d+$/.test(klass);
const findNum_parent_cat = klass => klass.replace(/\D+/, '');


$('[class^="parent_cat_"], [class*=" parent_cat_"]').on('change', function() {
  const klasses = [...this.classList];
  const klassIndex = klasses.findIndex(findIndex_parent_cat); // Get index
  const klass = klasses[klassIndex]; // Find it in classList
  const ID = findNum_parent_cat(klass); // Now let's extract the N number ID
  const cat_ID = `#cat_${ID}`; // Finally we have the ID...
  
  console.log(`${klass} found in classList at index ${klassIndex}. ID: ${cat_ID}`);
  
  $(cat_ID).prop({checked: this.checked});
});
<ul>
  <li class="main">
    <input type="checkbox" id="cat_6" class="something parent_cat_0 bla" name="local[]">
    <label class="strong" for="cat_6">Stellenbeschreibungen</label>
    <ul>
      <li class="main">
        <input type="checkbox" id="doc_31" class="blue red inp parent_cat_6 foo bar" name="local[]">
        <label for="doc_31">Stellenbeschreibung Marketing/Vertrieb</label>
      </li>
    </ul>
  </li>
</ul>

<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>

改为使用data-*属性!

这是对上述疯狂的重拍。
是的,请参见HTML如何在没有<label>属性的情况下使用for

$('[data-cat]').on('change', function() {

  const cat_ID = $(this).attr('data-cat'); // Finally we have the ID...
  console.log(`ID: ${cat_ID}`);
  
  $(cat_ID).prop({checked: this.checked});
});
<ul>
  <li class="main">
    <label>
      <input type="checkbox" id="cat_6" data-cat="#cat_0" name="local[]">
      Stellenbeschreibungen
    </label>
    <ul>
      <li class="main">
        <label>
          <input type="checkbox" id="doc_31" data-cat="#cat_6" name="local[]">
          Stellenbeschreibung Marketing/Vertrieb
        </label>
      </li>
    </ul>
  </li>
</ul>

<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>