Вот один из способов сделать это:
$(function(){
var cWrap=$('<div />');
$('p').each(function(){
var o = $(this).next('p').length;
$(this).replaceWith(cWrap).appendTo(cWrap);
if (!o) cWrap=$('<div />');
});
});
или как полноценный плагин:
(function($){
$.fn.wrapAll2 = function(wrapper){
if (!this.length) return this;
var cWrap=$(wrapper),
tag = this.get(0).nodeName.toLowerCase();
return this.each(function(){
var o = $(this).next(tag).length;
$(this).replaceWith(cWrap).appendTo(cWrap);
if (!o) cWrap = $(wrapper);
});
};
})(jQuery);
$(function(){
$('p').wrapAll2('<div />');
});
* Обратите внимание, что предполагается, что вы будете вызывать его в однородных коллекциях (как минимумвсе один и тот же тип узла)
EDIT
Экспериментально я изучил внутренности jQuery и обнаружил, что в нем хранится селектор, использованный для создания коллекции![по крайней мере, при создании экземпляра], поэтому, имея в виду, я создал другую версию, которая по крайней мере работает с текущей версией jQuery, и принимает любой селектор !
(function($) {
$.fn.wrapAll2 = function(wrapper) {
if (!this.length) return this;
var wrap = $(wrapper),
sel = this.selector || this.get(0).nodeName.toLowerCase();
return this.each(function() {
var more = $(this).next(sel).length;
console.log(this,more);
$(this).replaceWith(wrap).appendTo(wrap);
if (!more) wrap = $(wrapper);
});
}
})(jQuery);
$(function() {
$('p, span').wrapAll2('<div />');
});
It не работает с такими вещами, как это: $('p').add('span').wrapAll2('<div />');