【问题标题】:Find instance following given element在给定元素之后查找实例
【发布时间】:2014-09-06 05:34:02
【问题描述】:

我有一个关于使用 jquery 进行 dom 导航的问题。我正在尝试查找具有给定类的元素,该元素在给定元素之后的 dom 中最接近。

我有一个类似表格的结构,通过 div 创建并在 css 中设置样式。我有一个正在编辑的元素,当用户按下回车键时,我想关注以下可编辑元素。但是,它不是正在编辑的元素的兄弟。

HTML

<div class="calendarEntry">
  <div when="2014,9,18" class="when">Sep 18</div>
  <div class="items">
    <div class="item">
        <div code="ABC" class="type">ABC123</div>
        <div offered="2014,9,15" class="offered dateish">Sep 15
            <div class="offer editable">10</div>
            <div class="sku editable">TH1</div>
            <button>Publish</button>
        </div>
    </div>
    <div class="item">
        <div code="DEF" class="type">DEF321</div>
        <div offered="2014,9,14" class="offered dateish">Sep 14
            <div class="offer editable">10</div>
            <div class="sku editable">TH2</div>
            <button>Publish</button>
        </div>
    </div>
    <div class="item">
        <div code="GHI" class="type">GHI852</div>
        <div offered="2014,9,12" class="offered dateish">Sep 12
            <div class="offer editable">10</div>
            <div class="sku editable">TH3</div>
            <button>Publish</button>
        </div>
    </div>
  </div>
</div>

注意:页面上有多个日历条目。

假设用户正在编辑 DEF312 商品的报价。当他们按回车键时,我想编辑 GHI852 的报价。我有使 div 可编辑的代码,方法是将其替换为具有offer editing 类的文本字段。如果他们正在编辑此日历条目中的最终报价,则 Enter 键应聚焦以下日历条目的第一个可编辑报价(如果有)。如果我们在列表的底部,我不想回到顶部(我认为无论如何这会使事情过于复杂)。

我坚持的一点是如何找到下一个报价(所有报价都是可编辑的)。

这是我尝试过的:

var nextOffer = $('.offer').find('.editing').next('.editable');

显然,这行不通。问题是以下可编辑的报价不是正在编辑的当前报价的同级,因此next() 对我不起作用。以下报价可能在当前日历条目中,也可能在下一个日历条目中。无论哪种方式,它都在几个 div 之外,在不同的深度。

我什至可以使用 jquery dom 遍历来做到这一点,还是我最好只是通过 javascript 强制执行它(即循环遍历所有 .editable 实例并返回 .editing 之后的那个?

【问题讨论】:

  • 您是否尝试过使用.parent() 退出当前的可编辑报价并进入下一个?
  • 我认为你的问题是“item”的嵌套越来越深。结构不完全遵循逻辑顺序。
  • 是的,尝试了 parent() 和 parents() 的各种组合。无法解决。
  • 这是我的代码中的错字,我会修复它。谢谢。

标签: javascript jquery


【解决方案1】:

添加类'editing'来模拟输入:

<div class="item">
        <div code="DEF" class="type">DEF321</div>
        <div offered="2014,9,14" class="offered dateish">Sep 14
            <div class="offer editable">10</div>
            <div class="sku editable editing">TH2</div>
            <button>Publish</button>
        </div>
</div>

你可以这样做:

    function findEditable(currentItem) {

        var nextEditable = undefined,
            selectors = [".item", ".calendarEntry"];

        $.each(selectors , function (idx, selector) {

            var ref = currentItem.closest(selector);

            nextEditable = ref.parent()
                .children("div:gt(" + ref.index() + ")")
                .find(".offer.editable")
                .first();

            return nextEditable.length === 0;
        })


        return nextEditable;

    }

    findEditable($(".editing")).css({
        color: 'red'
    });

jsfiddle demo

【讨论】:

  • 谢谢@frankfg,但问题是下一个可编辑的报价可能在下一个日历条目中。鉴于此,父呼叫的数量会根据我是否正在编辑当前日历条目中的最后一个报价而变化。
  • 抱歉,希望新提案对您有所帮助。
  • 实际上,我并没有真正在寻找一个蛮力的 javascript 解决方案(因为我可以很容易地自己编写一个)。我正在寻找一个 jquery dom-navigation 解决方案。但是,此解决方案是唯一有效的解决方案,我可以复制/粘贴它而不是自己编写,所以我会接受它 - 谢谢。
【解决方案2】:

您可以使用parents() 来获取包含.offer 元素的.offered 元素,如下所示:

var offered = $('.offer').find('.editing').parents('.offered');

从中您可以使用next() 进入.offered 元素的兄弟.item 元素,并在其中找到.editable 元素:

offered.next('.item').find('.editable');

JSFiddle demo请注意,我已在您的 DEF321 项目的 .offer 元素中手动添加了此 .editing 元素 - 我假设这是在您这边动态添加的,但您的问题中不包含任何一种方式。


编辑:问题中的 HTML 现已更改。基于此,您将获得 .item 父级,而不是获得 .offered 父级:

var item = $('.offer').find('.editing').parents('.item');

并以与之前相同的方式进行:

item.next('.item').find('.editable');

JSFiddle demo.

【讨论】:

  • 感谢您的回答,但它并不适合我。它没有处理下一个可编辑的报价可能在以下日历条目中的事实。
  • @EngineerDollery 我已经更新了我的答案,以反映对您问题中代码所做的更改。
【解决方案3】:

试试这个

var current=document.activeElement,
    all=$(".editable"),
    index=all.indexOf(current),
    next=all[index+1]

它首先找到当前元素和元素列表,
然后它将在列表中找到当前元素。
然后它将向索引添加 1 并从列表中选择它。

用 indexOf 函数扩展数组;

if(!Array.prototype.indexOf){
  Array.prototype.indexOf=function(e/*,from*/){
    var len=this.length>>>0,
        from=Number(arguments[1])||0;
    from=(from<0)?Math.ceil(from):Math.floor(from);
    if(from<0)from+=l;
    for(;from<len;from++){
      if(from in this&&this[from]===e)return from;
    }
    return -1;
  };
}

【讨论】:

  • 有趣的方法。我在 Firefox 中收到错误,表明 indexOf 不是函数。有其他选择吗?
  • 可能firefox缺少array.indexOf函数,尝试通过prototype添加。大约一分钟后,示例如下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多