开发者

How to evaluate and group together matched elements

开发者 https://www.devze.com 2023-04-13 03:52 出处:网络
If my HTML looks something like: <div><h1>red</h1></div> <div><h1>red</h1></div>

If my HTML looks something like:

<div><h1>red</h1></div>
<div><h1>red</h1></div>
<div><h1>red</h1></div>
<div><h1>red</h1></div>
<div><h1>yellow</h1></div>
<div><h1>yellow</h1></div>
<div><h1>yellow</h1></div>
<div><h1>green</h1></div>
<div><h1>pink</h1></div>

What's the best approach in jQuery to evaluate how many h1 matches there are, and, if the match count is > 1 for a particular h1, put its div inside a container div:

<div class="matches">
    <div><h1>red</h1></div>
    <开发者_开发技巧;div><h1>red</h1></div>
    <div><h1>red</h1></div>
    <div><h1>red</h1></div>
</div>
<div class="matches">
    <div><h1>yellow</h1></div>
    <div><h1>yellow</h1></div>
    <div><h1>yellow</h1></div>
</div>
<div><h1>green</h1></div>
<div><h1>pink</h1></div>

I'm getting hung up with an each() function that returns every h1 to me, but I'm not sure if that's the best approach (jQuery newb trying to break into new territory).


var $containers = $('div'),
    $headings = $containers.find('> h1'),
    targetContainer = 'body',
    matches = {};

/*
 * First we traverse through the headings
 * pushing exact matches to a 'matches' object
 */
$headings.each(function() {
    var $this = $(this),
        text = $this.text();

    if (typeof matches[text] === 'undefined') {
        matches[text] = [];
    }

    matches[text].push($this.closest('div')[0]);
});

/*
 * Remove the initial, unsorted collection
 */
$containers.remove();

/*
 * Now let's see if we have duplicate
 * headings.
 */
for (group in matches) {
    if (matches[group].length > 1) {

        /*
         * Put them all in a '.matches' div
         * and append to our target container
         * e.g. body
         */
        $('<div class="matches"></div>').html(matches[group]).appendTo(targetContainer);

        /*
         * Delete the group
         * after use
         */
        delete matches[group];
    }
}

/*
 * This is optional:
 * I used two separate loops to
 * put unmatched headings after the
 * matched groups.
 *
 * You could use the if..else from
 * the previous loop.
 */

for (group in matches) {
    $(matches[group]).appendTo(targetContainer);
}

This code will work even with mixed, unordered collection, like

<div><h1>red</h1></div>
<div><h1>green</h1></div>
<div><h1>yellow</h1></div>
<div><h1>red</h1></div>
<div><h1>red</h1></div>
<div><h1>yellow</h1></div>
<div><h1>red</h1></div>
<div><h1>yellow</h1></div>
<div><h1>pink</h1></div>

UPDATE:

As I mentioned it is possible to keep matched and non-matched groups together — remove the second for..in loop and use the if..else as follows:

/* ...
 * Now let's see if we have duplicate
 * headings.
 */
for (group in matches) {
    if (matches[group].length > 1) {

        /*
         * Put them all in a '.matches' div
         * and append to our target container
         * e.g. body
         */
        $('<div class="matches"></div>').html(matches[group]).appendTo(targetContainer);
    } else {
        $(matches[group]).appendTo(targetContainer);
    }
}

However, due to the way JavaScript objects are stored in memory it is not possible to predict the order of enumeration.


    $('div').eq(0).before('<div class="matches">');

var  this_element= '';
var next_element = '';
var length = 0 ;
$('div').each(function(){

    this_element= $(this).find('h1').text();
    next_element = $(this).next('div').find('h1').text();


   if((this_element!= next_element) && (next_element!='') && (length>0)){

       $(this).after('</div><div class="matches">');
       length = 0 ;
   }
   if((!next_element) && (length>0)){
        $(this).after('</div>');
        length = 0 ;
   }
     length++;
});
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号