【问题标题】:Use jQuery to find previous occurence of class in Dom Tree使用 jQuery 在 Dom 树中查找先前出现的类
【发布时间】:2017-02-07 18:30:38
【问题描述】:

我想返回一个在 Dom 树的一部分中之前出现的类的对象,如果之前没有出现,那么我想被告知。

上一次出现的定义:在每个循环中,上一次出现的“21ld”来自 $(this) - 基本上是在您可以找到它的地方,当文本搜索整个“.window”类源代码向后查找来自 $ 的“21ld”时(这个)。

html(非常非常简化,实际结构非常混乱和不可预测):

<div class='window'>

    <div class='093a'>
          <div class='a9a3'>
                <div class='21ld'></div>
         </div>
         <div class='99l1'>
                <div class='uuu99l1'>
                    <div class='saved'></div>
                </div>
         </div>
    </div>
    <div class='i93d'>
          <div class='ad9l3'>
                <div class='ool1ld'></div>
         </div>
    </div>
    <div class='j93d'>
          <div class='aid9l3'>
                <div class='okl1ld'></div>
         </div>
    </div>
    <div class='a93d'>
          <div class='9l3'>
                <div class='21ld'></div>
         </div>
    </div>
    <div class='rbl1'> 
         <div class='4l1'>
                <div class='saved'></div>
         </div>
    </div>
    <div class='r0l1'> 
         <div class='0adl1'>
                <div class='0l1'>
                      <div class='21ld'></div>
                </div>
         </div
    </div>
</div>

js:

$('.window').find('.21ld').each(function(index){
      console.log($(this).fromHereFindPreviousOccurence('.saved'));
});

所以我期望输出:

1: undefined/false/whatever
2: jQuery Object of first saved class from my example
3: jQuery Object of second saved class from my example

如果有人可以在这里帮助我,我会很高兴吗? :)

【问题讨论】:

  • 为什么要这样做?我认为这里的答案会非常复杂,并且每次查找类时可能都需要遍历整个 DOM
  • "previous" 写在你的 HTML 中并不意味着与 DOM 树中的 previous 相同。我不认为你能按照书面的方式做到这一点。但正如@Cruiser 所说,如果您告诉我们为什么要这样做,我们可能会帮助您制定更好的解决方案。
  • 另一个函数保存 dom 中的元素,在这个函数中,我需要从源中每个循环中的元素向后退的最后一个“.saved”元素的数据值。
  • 当我们说您为什么要这样做时,我们真正要问的是,您通过获取此信息试图解决的原始问题是什么。不仅仅是您的解决方案中调用它的上一步/函数。
  • 我正在从对话线程中抓取单个元素 - 混乱的 html 结构是整个对话线程 - 我正在挑选某些部分并保存它们,然后通过添加类将它们标记为已保存。然后在更新这个线程时,我想知道每个周期中的 $(this) 是否发生在整个线程中的“.save”类之后,如果是这样,我想从找到的类实例中获取数据。

标签: javascript jquery html screen-scraping


【解决方案1】:

这个 sn-p 将遍历 DOM 以找到以前的保存。只有结构保持不变,它才会起作用。如果父 div 类名有一些押韵或理由,那么你可以写得更好。

var $window = $('.window'),
  //immediate div children
  $parentContainers = $('.window > div');

$window.find('.21ld').each(function() {
  var $currentElement = $(this),
    $prevSave;

  $parentContainers.each(function(i) {
    var $this = $(this),
      parentContainer = $(this).find($currentElement).length > 0,
      $innerSave = $this.find('.saved');

    if (parentContainer) {
      //breaks out of iteration if we've found the current element
      return false;
    } else if ($innerSave.length > 0) {
      //cache the most recent save elemen
      $prevSave = $innerSave;
    }
  });

  var text = typeof $prevSave === 'undefined' ? 'undefined' : $prevSave.text(),
    parent = typeof $prevSave === 'undefined' ? '' : ' in ' + $prevSave.parent().attr('class')

  //shows results using the parent class names
  console.log($currentElement.parent().attr('class') + ' found ' + text + parent);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class='window'>
  <div class='093a'>
    <div class='a9a3'>
      <div class='21ld'></div>
    </div>
    <div class='99l1'>
      <div class='uuu99l1'>
        <div class='saved'>first save</div>
      </div>
    </div>
  </div>
  <div class='i93d'>
    <div class='ad9l3'>
      <div class='ool1ld'></div>
    </div>
  </div>
  <div class='j93d'>
    <div class='aid9l3'>
      <div class='okl1ld'></div>
    </div>
  </div>
  <div class='a93d'>
    <div class='9l3'>
      <div class='21ld'></div>
    </div>
  </div>
  <div class='rbl1'>
    <div class='4l1'>
      <div class='saved'>second save</div>
    </div>
  </div>
  <div class='r0l1'>
    <div class='0adl1'>
      <div class='0l1'>
        <div class='21ld'></div>
      </div>
    </div </div>
  </div>

【讨论】:

  • 你直击我的问题 ;) 我最大的问题是在 $(this) 之上可能有动态数量的父母,我永远不知道要上升多少级。类名每次也不同,.saved 和 21ld 嵌套的级别也是如此,按类名我只能遍历到“.window”,此时我将完全忘记我来自哪里。
  • 我更新了我的问题中的代码以反映一点
  • @Jessica 为您更新了 sn-p。它可以更好地优化,但我现在不能花太多时间在它上面。希望对您有所帮助。
【解决方案2】:

自从我使用 jQuery 以来已经有一段时间了,但我刚刚测试了这个,我认为它应该可以工作。

编辑:我意识到这不一定每次都返回最近的实例。为了实现你想要的,你实际上必须扩展你对先前或最近的定义,因为一旦你沿着树走一定距离,最接近另一个元素的元素在定义上变得有点相对。

function findClass(el, needle) {
    let element = el

    while (element.nodeName !== 'HTML') {

        if ($(element).find(needle).length) {
            return $(element).find(needle)
        }

        element = element.parent()
    }
}

【讨论】:

  • 我添加了一个定义,实际的 dom 树太复杂了,这样的东西无法正常工作,我总是需要前一个(如文本中的前一个单词)出现
  • @Jessica 我明白你的意思了,从上面的内容开始,或者某种递归函数是你想要去的方向,但考虑到关系“亲密",一旦您与原始节点有一定距离,您可能最终会想要找到一个类的 last 实例。
【解决方案3】:

所以你可以使用.prev()jQuery reference. JS 看起来像这样:

$(window).each('.21ld', function (i){
    var saved =$(this).prev('.saved');
    console.log(saved);
    if(saved.length < 0){
        console.log('.saved not found on occurance: ' + i);
    }
});

【讨论】:

  • 这在我的用例中不起作用,因为 $(this) 可以位于比 .saved 类完全的地方——它们都只在“.window”中,而不是它们在完全不同的树上
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
相关资源
最近更新 更多