JSFiddle - React, Tailwind, and code Playground

by russcam

HTML

<p>anchors wrapped in groups of 4 including non-matching child elements</p>
<div> 
    <a href="#">1</a>
    <a href="#">2</a>
    <p>Child element that will be ignored</p>
    <a href="#">3</a>
    <a href="#">4</a>
    <p>Another that will be ignored</p>
    <a href="#">5</a>
    <a href="#">6</a>
    <a href="#">7</a>
    <p>Yet another that will be ignored</p>
    <a href="#">8</a>
    <p>And another</p>
    <a href="#">9</a>
    <a href="#">10</a>
</div>
<br/>
<p>anchors wrapped in groups of 4</p>
<div> 
     <a href="#">1</a>
     <a href="#">2</a>
     <a href="#">3</a>
     <a href="#">4</a>
     <a href="#">5</a>
     <a href="#">6</a>
     <a href="#">7</a>
     <a href="#">8</a>
     <a href="#">9</a>
     <a href="#">10</a>
 </div>

CSS

.wrapper { background-color: red; margin: 5px; }

JavaScript

(function($){
    $.fn.wrapChildren = function(options) {

        options = $.extend({
                              childElem : undefined,
                              groupSize : 1,
                              wrapper : '<div>'
                            }, options || {});
                            
        if (options.childElem === undefined) return this;

        return this.each(function() {
            var elems = $(this).children(),
                len = pos = 0;
            
            elems.each(function(i,value) {
                len += $(value).is(options.childElem)? 1 : 0;                    
                if (len > 0 && (len % options.groupSize === 0) || (i === elems.length - 1)) {          
                  elems.slice(pos,i + 1).wrapAll(options.wrapper);
                  len = 0;
                  pos = i + 1;
                }
            });
        }); 
        
    }
})(jQuery);

$(function() {

    $('div').wrapChildren({ childElem : 'a' , groupSize: 4, wrapper : '<div class="wrapper">' });

});