if I have this html
开发者_如何学编程<div>
<p>1</p>
</div>
<div>
<p>1</p>
<p>2</p>
</div>
and this jquery
$('div').each(function () {
$(this).find('p').eq(1).html('test');
});
i get this
<div>
<p>1</p>
</div>
<div>
<p>1</p>
<p>test</p>
</div>
what jquery should I use to get this instead?
<div>
<p>1</p>
<p>test</p>
</div>
<div>
<p>1</p>
<p>test</p>
</div>
there is no match for eq(1)
on the first div so it just skips it. how can I add a child if none exists or update it if one does exist, without having to split the jquery into several statements?
If your <div>
elements contain at most two paragraphs, you can do:
$("div").each(function() {
var $this = $(this);
$this.find("p").add($("<p>")).eq(1).html("test").appendTo($this);
});
If there are more than two paragraphs, things get more complicated and you'll have to use insertAfter() instead of appendTo() to add the new element to the DOM:
$("div").each(function() {
var $this = $(this);
$this.find("p").add($("<p>")).eq(1).html("test")
.insertAfter($this.find("p").eq(0));
});
You can see the results in this fiddle.
The easiest way i found is this lets see someone else come with smaller solution
<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/
In the interest of keeping a separation of concerns, here's an jQuery function that will either locate an existing element or create a new element.
So just include this jQuery anywhere:
$.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;
};
Then you could use like this:
$("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)
})
Ideally, it would be nice to simply pass in a selector and have jQuery create an element that matches that selector automatically, but it doesn't seem like there's a light weight vehicle for creating an element based off the CSS Selector syntax (based on Question 1 & Question 2).
Some further enhancements might provide more fine tuned control for DOM insertion instead of just always using .append()
.
Demo in jsFiddle | Demo in 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>
精彩评论