【问题标题】:jquery create new child, or update existing childjquery 创建新的孩子,或更新现有的孩子
【发布时间】:2011-08-07 06:33:13
【问题描述】:

如果我有这个 html

<div>
  <p>1</p>
</div>

<div>
  <p>1</p>
  <p>2</p>
</div>

还有这个 jquery

$('div').each(function () {
    $(this).find('p').eq(1).html('test');
});

我明白了

<div>
  <p>1</p>
</div>

<div>
  <p>1</p>
  <p>test</p>
</div>

我应该使用什么 jquery 来代替?

<div>
  <p>1</p>
  <p>test</p>
</div>

<div>
  <p>1</p>
  <p>test</p>
</div>

第一个 div 上的 eq(1) 没有匹配项,所以它只是跳过它。如果不存在子项,我如何添加子项,如果存在则更新子项,而无需将 jquery 拆分为多个语句?

【问题讨论】:

  • without having to split the jquery into several statements 是什么意思? if 语句是否被禁止?
  • 我的理解是,如果做同样的事情并且易于理解,1 行代码通常比 5 行代码要好。

标签: jquery jquery-selectors


【解决方案1】:

如果您的&lt;div&gt; 元素最多包含两个段落,您可以这样做:

$("div").each(function() {
    var $this = $(this);
    $this.find("p").add($("<p>")).eq(1).html("test").appendTo($this);
});

如果有两个以上的段落,事情会变得更加复杂,您必须使用insertAfter() 而不是appendTo() 来将新元素添加到 DOM:

$("div").each(function() {
    var $this = $(this);
    $this.find("p").add($("<p>")).eq(1).html("test")
         .insertAfter($this.find("p").eq(0));
});

你可以在this fiddle看到结果。

【讨论】:

  • 请问您为什么将 $(this) 更改为 $this?
  • @Joey,给$()打电话,这样代码会稍微快一点。这种做法通常称为缓存$(this)
【解决方案2】:

我发现的最简单的方法是让我们看看其他人提供更小的解决方案

<div>
  <p>1</p>
</div>

<div>
  <p>1</p>
  <p>2</p>
</div>

$('div').each(function () {
    var elm= $(this).find('p').eq(1);
    if(elm.length==0)
    {
        $(this).find('p').after('test');
    }
    else
    {
        elm.html('test')
    }
});

http://jsfiddle.net/geBXF/

【讨论】:

  • 是的,这基本上也是我想出的。我希望比我更熟悉 jquery 的人会知道更简洁的语法
【解决方案3】:

为了保持关注点分离,这里有一个 jQuery 函数,它将定位现有元素或创建新元素。

所以只要在任何地方包含这个 jQuery:

$.fn.upsert = function(selector, htmlString) {
  // upsert - find or create new element
  // find based on css selector     https://api.jquery.com/category/selectors/
  // create based on jQuery()       http://api.jquery.com/jquery/#jQuery2
  var $el = $(this).find(".message");
  if ($el.length == 0) {
    // didn't exist, create and add to caller
    $el = $("<span class='message'></span>");
    $(this).append($el);
  }

  return $el;
}; 

那么你可以这样使用:

$("input[name='choice']").click(function(){
  var $el = $(this).closest("form").upsert(".message", "<span class='message'></span>");
  // guaranteed to have element - update if we want
  $el.html("You've chosen "+this.value)
})

理想情况下,最好简单地传入一个选择器并让 jQuery 创建一个自动匹配该选择器的元素,但似乎没有基于 CSS 选择器语法的 creating an element 的轻量级工具(基于Question 1 & Question 2)。

一些进一步的增强可能会为DOM insertion 提供更精细的控制,而不仅仅是始终使用.append()

Demo in jsFiddle | Stack Snippets 中的演示:

$.fn.upsert = function(selector, htmlString) {
  // upsert - find or create new element
  // find based on css selector   	https://api.jquery.com/category/selectors/
  // create based on jQuery()       http://api.jquery.com/jquery/#jQuery2
  var $el = $(this).find(".message");
  if ($el.length == 0) {
    // didn't exist, create and add to caller
    $el = $("<span class='message'></span>");
    $(this).append($el);
  }

  return $el;
}; 

$("input[name='choice']").click(function(){
  var $el = $(this).closest("form").upsert(".message", "<span class='message'></span>");
  // guaranteed to have element - update if we want
  $el.html("You've chosen "+this.value)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form action="">
  <div>
    <input type="radio" id="ca" name="choice" value="A" /><label for='ca'>A</label>
    <input type="radio" id="cb" name="choice" value="B" /><label for='cb'>B</label>
    <input type="radio" id="cc" name="choice" value="C" /><label for='cc'>C</label>
  </div>
</form>

【讨论】:

    猜你喜欢
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 2018-09-17
    • 2018-11-24
    • 2018-09-15
    • 2012-10-11
    相关资源
    最近更新 更多