Pregunta

I am curious why jQuery's .after() does not chain, or "provide you with," the new element that you create with it. It seems to me like it should, but I am no expert and was hoping someone could shed some light on why it's a bad idea. Here's an example to see what I would like from .after():

Here is some markup:

<div id="content1">
    <p id="hello1">Hello</p>
</div>
<div id="content2">
    <p id="hello2">Hello</p>
</div>

Here's what I want, but this replaces "Hello" with "World!":

$('#hello1').after('<p />').text('World!');

This does the job, but it sure is ugly:

$('#hello2').after('<p />');
var $newParagraph = $('#content2 p').last();
$newParagraph.text('World');

This is nicer, but I'm not entirely sold: (maybe I should be?)

$('#hello1').after( $('<p />').text('World') );

Note this is obviously a simplified example, that is, "<p>World!</p>" is not what I want to add, my real world problem is more complex than that.

Thanks for any thoughts.

¿Fue útil?

Solución

Presumably .after() works as it does to allow you to chain more methods that would apply to the originally selected element(s):

$('#hello1').after( $('<p />').text('World') )
            .before( $('<p />').text('Before text') )
            .remove();

This keeps the behaviour consistent with other methods, so you don't have to try to remember which ones return the original object and which return some other object.

Note that in your case $('#hello1') selects exactly one element since you are selecting by id, but you can apply .after() to a jQuery object containing many elements to add (cloned) content after multiple elements:

$('div.someclass').after( $('<p/>').text('whatever') );

In which case in my opinion it definitely makes sense to keep the chaining context as the original jQuery object.

The .insertAfter() method might be closer to what you want:

$('<p/>').insertAfter('#hello1').text('World');

(It also returns the jQuery object it was applied to, but it does the insert in "reverse".)

You could write your own plugin method to return the element being added, but that would be confusing since it would work opposite to all the standard methods.

Otros consejos

That's just how it is for most jQuery methods. It's better for jQuery to be consistent and return the original object.

The fix is this:

$('#hello1').after(
    $('<p/>', { text: 'World!' })
);

or:

$('#hello1').after(
    $('<p/>').text('World!')
);

or even:

$('<p/>').text('World!').insertAfter('#hello1');

The latter may actually be preferred since it does then continue to chain from the new <p> element.

It doesn't provide you with the created element because you don't always create an element, it would require a significant amount of processing power for JQuery to detect that a element is created and it makes much more sense to always have it return the element witch was the target of the operation.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top