简体   繁体   中英

Easiest way to alternate row colors in PHP/HTML?

Here's a PHP example of mine. Can anyone find a shorter/easier way to do this?

<? foreach($posts as $post){?>
    <div class="<?=($c++%2==1)?‘odd’:NULL?>">
        <?=$post?>
    </div>
<? }?>

<style>
    .odd{background-color:red;}
</style>

Examples in other languages would be fun to see as well.

Fundamentally - no. That's about as easy as it gets. You might rewrite it a bit shorter/cleaner, but the idea will be the same. This is how I would write it:

$c = true; // Let's not forget to initialize our variables, shall we?
foreach($posts as $post)
    echo '<div'.(($c = !$c)?' class="odd"':'').">$post</div>";

If you'd like to have less in-line PHP, a great way of doing it is via JavaScript.

Using jQuery, it's simply:

<script type="text/javascript">
$('div:odd').css('background-color', 'red');
</script>

Using CSS3 you can do something like this:

div:nth-child(odd)
{
  background-color: red
}

But better not use that for a few years if you actually want your users to see the color...

Smarty has it inbuilt:

{section name=rows loop=$data}
<tr class="{cycle values="odd,even"}">
   <td>{$data[rows]}</td>
</tr>
{/section}

So does Django:

{% for o in some_list %}
    <tr class="{% cycle 'row1' 'row2' %}">
        ...
    </tr>
{% endfor %}

i always name my zebra rows "row0" and "row1" - this makes the code a bit simpler.

<?php  // you should always use the full opening tag for compatibility
$i = 0;
foreach ($rows as $row) {
    echo '<tr class="row' . ($i++ % 2) . '">...</tr>';
} 
?>

Maybe a function with a static variable?

<?php

function alternate_row_color($css_class) {
    static $show = true;

    $show = !$show;

    if ($show) {
        return $css_class;
    } else {
        return NULL;
    }
}

?>

Then to use it (using your example):

<?php foreach($posts as $post) { ?>
    <div class="<?=alternate_row_color('odd')?>">
        <?=$post?>
    </div>
<?php } ?>
<?php $alt = true; foreach ($posts as $post): $alt = !$alt; ?>
<div<?php echo $alt ? ' class="odd"' : ''; ?>>
    <!-- Content --> 
</div>  
<?php endforeach ?>

Would be the simplest and clearest way to do it.

Just for fun

Assuming you can use CSS3 selectors you can do something like

<div class="posts">
<? foreach($posts as $post){?>
    <div>
        <?=$post?>
    </div>
<? }?>
</div>

<style>
    div.posts div:odd{background-color:red;}
</style>

Even with CSS2 support and mootools (javascript library) you can substitute the style with this javascript

<script type="text/javascript">
    // obviously this script line should go in a js file in a onload (or onDomReady) function
    $$('div.posts div:odd').setStyle('background-color','red');
</script>

If you don't have anything but php a it you can simplify a bit yous code using an array

<? $isodd=array('','odd');
   $c=0;
   foreach($posts as $post){?>
    <div class="<?=$isodd[$c++%2]?>">
        <?=$post?>
    </div>
<? }?>

You can encapsulate the logic as follows:

<?php

class ListCycler {
    private $cols, $offs, $len;

    // expects two or more string parameters
    public function __construct() {
        $this->offs = -1;
        $this->len = func_num_args();
        $this->cols = func_get_args();

        foreach($this->cols as &$c)
            $c = trim(strval($c));
    }

    // the object auto-increments every time it is read
    public function __toString() {
        $this->offs = ($this->offs+1) % $this->len;
        return $this->cols[ $this->offs ];
    }
}
?>
<html>
<head>
  <style>
    ul#posts li.odd { background-color:red; }
    ul#posts li.even { background-color:white; }
  </style>
</head>
<body>
  <div>
    <h3>Posts:</h3>
    <ul id="posts"><?php
        $rc = new ListCycler('odd','even');
        foreach($posts as $p)
            echo "<li class='$rc'>$p</li>";
    ?></ul>
  </div>
</body>
</html>

You can abuse the $GLOBAL scope to store the current selected class state, see below table_row_toggle() function. Yes, I know its dirty to abuse the $GLOBAL scope, but hey, we're here to fix problems ain't we? :)

Calling the table row toggle function in HTML:

<tr <? table_row_toggle(); ?>>

The function in PHP:

/* function to toggle row colors in tables */
function table_row_toggle() {
    /* check if $trclass is defined in caller */
    if(array_key_exists('trclass', $GLOBALS)) {
        $trclass = $GLOBALS['trclass'];
    }   

    /* toggle between row1 and row2 */
    if(!isset($trclass) || $trclass == 'row2') {
        $trclass = 'row1';
    } else {
        $trclass = 'row2';
    }   

    /* set $trclass in caller */
    $GLOBALS['trclass'] = $trclass;

    /* write the desired class to the caller */
    echo ' class="' . $trclass . '"';
}
    <?php   ($i%2==1) ? $bgc='#999999' : $bgc='#FFFFFF'; ?>
    '<div bgcolor=" bgcolor='.$bgc.'">';

在Vilx上发现但是,速度总是很小(页面重量)

<tr class="'.(($c = !$c)?'odd':'even').'">
function row_color($cnt,$even,$odd) { 
echo ($cnt%2) ? "<tr bgcolor=\"$odd\">" : "<tr bgcolor=\"$even\">"; 
} 

How to use:

$cnt=0;
while ($row = mysql_fetch_array ($result)) {
row_color($cnt++,"e0e0e0","FFFFFF");
}

It's short enough as it is, but I would probably wrap it into some helper function with a clear name. That way it's more obvious what's going on and you won't have to repeat that logic in all templates where you need it.

If you want to do it on the display end and are comfortable with or otherwise already using javascript, libraries like jQuery will often have :odd and :even selectors, which you can then hook up to adding specific style properties or hooking into CSS more generally by adding classes .

On a side noe, to alternate between two values a and b , a nice way of doing it in a loop is this:

x = a;
while ( true ) {
    x = a + b - x;
}

You can also do this without addition and subtraction:

x = a ^ b ^ x;

where ^ is the XOR operation.

If you just want to alternate between 0 and 1, you can do this:

x = 0;
while ( true ) {
    x = !x;
}

You could of course use x as an index of colors, CSS style classes and so on.

In PHP I am using this code:

function alternate($sEven = "even", $sOdd = "odd")
{
    static $iCount;
    return ($iCount++ & 1) ? $sOdd :$sEven;
}

for($i = 0; $i< 5; $i++)
echo alternate();


/*output:

even
odd
even
odd
even

*/

Source: http://sklueh.de/2013/11/einfache-alternierung-mit-php/

Been using something like this:

<?php
function cycle(&$arr) {
    $arr[] = array_shift($arr);
    return end($arr); 
}

$oddEven = array('odd', 'even');
echo cycle($oddEven)."\n";
echo cycle($oddEven)."\n";
echo cycle($oddEven)."\n";

A simple little function that works well for me.

 <?php 
class alternating_rows()
{
    private $cycler = true;
//------------------------------------------------------------------------------
    function rowclass($row0,$row1)
    {
        $this->cycler = !$this->cycler;//toggle the cycler
        $class=($this->cycler)?$row0:$row1;
        return $class;
    }// end function rowclass
//------------------------------------------------------------------------------    

}//end class alternating rows
?>
<?php $tablerows= new alternating_rows();?>
<table>
  <tr>
    <th scope="col">Heading 1</th>
    <th scope="col">Heading 2</th>
  </tr>
  <?php foreach ($dataset as $row){?>
  <tr class="<?php echo $tablerows->rowclass("oddrow","evenrow"); ?>">
    <td>some data</td>
    <td>some more data</td>
  </tr>
  <?php } //end foreach?>
</table> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM