jQuery选择直接“父元素”,而非类似的

3
我得到了一个固定的表结构,就像这个例子:
<table>
    <tr><td class="lvl-0">1</td><tr>
    <tr><td class="lvl-1">2</td><tr>
    <tr><td class="lvl-2">3</td><tr>
    <tr><td class="lvl-2">4</td><tr>
    <tr><td class="lvl-2">5</td><tr>
    <tr><td class="lvl-1">6</td><tr>
    <tr><td class="lvl-2">7</td><tr>
    <tr><td class="lvl-2 selected">8</td><tr>
    <tr><td class="lvl-2">9</td><tr>
</table>

我希望选择每个级别的父级。

这意味着我想选择之前选中的每个级别,除了相似的。在此示例中,这将是6和1。

我尝试使用以下代码:

var ss = [];
for(var l = lvl; l <= 5; l++){
    ss.push('td.lvl-'+l);
}
var ul = jQuery('table').find(ss.join(',')).closest('tr');
var pa = jQuery('.selected').closest('tr').prevAll('tr').not(ul);

但它也选择了第二个数字

// 编辑

我有一个jsfiddle http://jsfiddle.net/g7yhwojg/3/ 应该选择的是:

  • 14
  • 13
  • 10
  • 1

不,它不是来自8的直接父级。其父级是6(lvl-1)和1(lvl-0),而不是2(lvl-1)。 - Jason Schilling
你上面的代码和fiddle代码有所不同。在上面的代码中,你使用了class="lvl-2 selected",而在fiddle中你使用了id="selected" - vijayP
@J.Schilling 你打算做什么? - Himesh Aadeshara
1
@J.Schilling,您在选择14、13、10、1时使用的是哪个进制?它们之间有什么共同点吗? - Himesh Aadeshara
1
@J.Schilling 嗨,我觉得你在复制粘贴时错过了关闭 </tr> 的代码标记,这可能是一个问题。 - Himesh Aadeshara
显示剩余7条评论
2个回答

5

我自己搞定了。

var lvls = [];
pa = pa.filter(function(){
    var pc = jQuery(this).find('td').attr('class');
    if(lvls.indexOf(pc) == -1){
        console.log(pc);
        lvls.push(pc);
        return true;
    }
    return false;
});

我遍历了所有的上层元素,并且每次仅仅选择第一个元素。

http://jsfiddle.net/g7yhwojg/11/


3
自己找到了的话加一分... :) - Guruprasad J Rao
1
我也写了类似的解决方案。很高兴你自己完成了。再加一。 - shashwat

1

虽然你已经发布了自己的答案,但我想提供一个替代方案,以防你感兴趣:

// caching the selected element (selecting by its id):
var selected = $('#selected'),

// caching the regular expression, in case it might be
// be needed again later; this matches a serious of
// one or more (+) numbers (\d) at the end of the
// string ($):
    levelRegex = /\d+$/,

// finding the numbers at the end of the selected
// element's class attribute, and using parseInt()
// to convert that to a number in base-10:
    selectedLevel = parseInt(selected.attr('class').match(levelRegex), 10),

// caching the selected element's closest ancestor
// <tr> element:
    selectedParent = selected.closest('tr'),

// caching the <tr> elements before the selectedParent:
    rowsBefore = selectedParent.prevAll(),

// using map() to iterate over those elements and
// if their child <td> element has a class equal to
// 'lvl-' + (selectedLevel - 1)
// we first decrement selectedLevel, and then
// return the text of the current <tr> element;
// decrementing here means we can only ever
// retrieve the first instance of an element
// with a 'lower' level:
    pseudoParents = rowsBefore.map(function (i) {
        if ($(this).find('td').hasClass('lvl-' + (selectedLevel - 1))) {
            --selectedLevel;
            return this.textContent;
        }

// converting the 'map' into a native Array:
    }).get();

console.log(pseudoParents);
// ["14", "13", "10", "1"]

var selected = $('#selected'),
  levelRegex = /\d+$/,
  selectedLevel = parseInt(selected.attr('class').match(levelRegex), 10),
  selectedParent = selected.closest('tr'),
  rowsBefore = selectedParent.prevAll(),
  pseudoParents = rowsBefore.map(function(i) {
    if ($(this).find('td').hasClass('lvl-' + (selectedLevel - 1))) {
      --selectedLevel;
      return this.textContent.trim();
    }
  }).get();

// snippet logs to the bottom of the result panel:
snippet.log(pseudoParents);

// logs to the console (obviously):
console.log(pseudoParents);
// ["14", "13", "10", "1"]
.lvl-0 {
  padding-left: 10px;
}
.lvl-1 {
  padding-left: 30px;
}
.lvl-2 {
  padding-left: 50px;
}
.lvl-3 {
  padding-left: 70px;
}
.lvl-4 {
  padding-left: 90px;
}
.lvl-5 {
  padding-left: 110px;
}
body {
  color: #ffffff;
  background: #000000;
}
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td class="lvl-0">1</td>
  </tr>
  <tr>
    <td class="lvl-1">2</td>
  </tr>
  <tr>
    <td class="lvl-2">3</td>
  </tr>
  <tr>
    <td class="lvl-2">4</td>
  </tr>
  <tr>
    <td class="lvl-2">5</td>
  </tr>
  <tr>
    <td class="lvl-1">6</td>
  </tr>
  <tr>
    <td class="lvl-2">7</td>
  </tr>
  <tr>
    <td class="lvl-2">8</td>
  </tr>
  <tr>
    <td class="lvl-2">9</td>
  </tr>
  <tr>
    <td class="lvl-1">10</td>
  </tr>
  <tr>
    <td class="lvl-2">11</td>
  </tr>
  <tr>
    <td class="lvl-2">12</td>
  </tr>
  <tr>
    <td class="lvl-2">13</td>
  </tr>
  <tr>
    <td class="lvl-3">14</td>
  </tr>
  <tr>
    <td class="lvl-4">15</td>
  </tr>
  <tr>
    <td class="lvl-4" id="selected">16</td>
  </tr>
  <tr>
    <td class="lvl-3">17</td>
  </tr>
  <tr>
    <td class="lvl-1">18</td>
  </tr>
  <tr>
    <td class="lvl-2">19</td>
  </tr>
  <tr>
    <td class="lvl-2">20</td>
  </tr>
  <tr>
    <td class="lvl-2">21</td>
  </tr>
</table>

外部JS Fiddle演示,用于实验和开发。

请注意,在Stack Snippet和JS Fiddle中,我已经更正了HTML以关闭<tr>元素,否则每行<table>的末尾错误的<tr>标签会不必要地创建一个新的空<tr>

参考资料:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接