Вот мой пример PHP. Может ли кто-нибудь найти более короткий / простой способ сделать это?
<? foreach($posts as $post){?>
<div class = "<?=($c++%2==1)?‘odd’:NULL?>">
<?=$post?>
</div>
<? }?>
<style>
.odd{background-color:red;}
</style>
Было бы интересно увидеть примеры на других языках.






Принципиально - нет. Это почти так просто. Вы можете переписать его немного короче / чище, но идея останется той же. Вот как я бы это написал:
$c = true; // Let's not forget to initialize our variables, shall we?
foreach($posts as $post)
echo '<div'.(($c = !$c)?' class = "odd"':'').">$post</div>";
Спасибо, работает отлично. Вот что я изменил, чтобы чередовать два класса TR (нечетный и четный) <? Php echo '<tr'. (($ C =! $ C)? 'Class = "odd"': 'class = "even" '). ">"; ?>
Спасибо за это решение! Большой!
Может быть, функция со статической переменной?
<?php
function alternate_row_color($css_class) {
static $show = true;
$show = !$show;
if ($show) {
return $css_class;
} else {
return NULL;
}
}
?>
Затем использовать его (используя ваш пример):
<?php foreach($posts as $post) { ?>
<div class = "<?=alternate_row_color('odd')?>">
<?=$post?>
</div>
<?php } ?>
Вы определяете функцию только один раз, а затем получаете красивый короткий и очень читаемый вызов функции везде, где хотите ее использовать.
Это кажется довольно хорошим примером, но кажется, что для этих основ неплохо иметь фрагмент, который вы можете просто добавить всякий раз, когда он появляется.
статика может быть трудной для чтения / понимания на первый взгляд. Идиома в OP лучше понятна. Кроме того, это не работает, если у вас есть более одного элемента, чередующегося одновременно (например, строки, а затем столбцы будут разбиты на нечетное количество столбцов).
Он и так достаточно короткий, но я бы, вероятно, превратил его в какую-нибудь вспомогательную функцию с понятным именем. Так будет более очевидно, что происходит, и вам не придется повторять эту логику во всех шаблонах, где она вам нужна.
<?php $alt = true; foreach ($posts as $post): $alt = !$alt; ?>
<div<?php echo $alt ? ' class = "odd"' : ''; ?>>
<!-- Content -->
</div>
<?php endforeach ?>
Это был бы самый простой и понятный способ сделать это.
почти то же самое, что и @ Vilx- (который писал ранее), но тем не менее хороший.
В Smarty встроено:
{section name=rows loop=$data}
<tr class = "{cycle values = "odd,even"}">
<td>{$data[rows]}</td>
</tr>
{/section}
Как и Django:
{% for o in some_list %}
<tr class = "{% cycle 'row1' 'row2' %}">
...
</tr>
{% endfor %}
В Rails: <% some_list.each do | list | %> <tr class = <% = cycle ('нечетный', 'четный')%> ... </tr> <% end%>
Используя CSS3, вы можете сделать что-то вроде этого:
div:nth-child(odd)
{
background-color: red
}
Но лучше не использовать это в течение нескольких лет, если вы действительно хотите, чтобы ваши пользователи видели цвет ...
Если вы хотите сделать это на стороне дисплея и вам комфортно или иным образом уже используется javascript, библиотеки, такие как jQuery, часто будут иметь селекторы :странный и :четный, которые затем вы можете подключить для добавления определенного свойства стиля или подключения к CSS в более общем случае с помощью добавление классов.
Если вы хотите иметь меньше встроенного PHP, отличный способ сделать это - использовать JavaScript.
Используя jQuery, это просто:
<script type = "text/javascript">
$('div:odd').css('background-color', 'red');
</script>
Я не использую jQuery, но похоже, что это хороший чистый фрагмент кода.
Я тоже поддерживаю это. Изменение цвета ячеек с нечетными номерами - это проблема дизайна, поэтому было бы лучше иметь дело в JS или CSS, а не в бизнес-логике (PHP).
@Bob: PHP здесь распечатывает HTML, который и так является частью логики представления.
PHP или CSS3 - гораздо лучшие методы для этого, чем javascript, без перекомпоновки и без F.O.U.C.
Не является хорошей практикой помещать такое поведение в Javascript.
Если вам все еще нужен javascript, лучше написать $('div:odd').addClass('odd');, а затем стилизовать этот класс в своем CSS. Не устанавливайте стили в javascript.
Не забывай! Если вы используете решение Javascript (jquery, прототип или что-то еще), у вас будет небольшой щелчок при загрузке страницы. Фактически, пока страница не загрузится полностью, в ваших строках не будет «зебры». Для некоторых людей это может быть проблемой.
Просто для развлечения
Предполагая, что вы можете использовать селекторы CSS3, вы можете сделать что-то вроде
<div class = "posts">
<? foreach($posts as $post){?>
<div>
<?=$post?>
</div>
<? }?>
</div>
<style>
div.posts div:odd{background-color:red;}
</style>
Даже с поддержкой CSS2 и mootools (библиотека javascript) вы можете заменить стиль этим 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>
Если у вас нет ничего, кроме php, вы можете немного упростить свой код, используя массив
<? $isodd=array('','odd');
$c=0;
foreach($posts as $post){?>
<div class = "<?=$isodd[$c++%2]?>">
<?=$post?>
</div>
<? }?>
Это сгенерирует предупреждение на первой итерации, поскольку $ c не инициализирован, а также вы ссылаетесь на 'c', когда вы должны ссылаться на '$ c', что приведет либо к ошибке, либо предупреждению, либо к неэффективному поведению. Не могу вспомнить какой.
@ Брайан Клайн: спасибо за ваш комментарий. Отредактировал сообщение согласно;
Вы можете инкапсулировать логику следующим образом:
<?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>
должен __get () не быть __toString ()?
Почему обрезка ()? Это делает класс менее удобным.
Ух ты. У вас очень-очень странное представление о «попроще»
nickf: (ухмыляется) Ну, очевидно, вы пишете класс ListCycler один раз и сохраняете его в коде вашей библиотеки. Когда вы его использовать, это очень просто - создайте объект ListCycler, затем вызовите его несколько раз, вся логика скрыта.
С другой стороны, для переключения между двумя значениями а и б, хороший способ сделать это в цикле:
x = a;
while ( true ) {
x = a + b - x;
}
Вы также можете сделать это без сложения и вычитания:
x = a ^ b ^ x;
где ^ - операция XOR.
Если вы просто хотите чередовать 0 и 1, вы можете сделать это:
x = 0;
while ( true ) {
x = !x;
}
Конечно, вы можете использовать Икс в качестве индекса цветов, классов стилей CSS и так далее.
Использовал что-то вроде этого:
<?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";
Я всегда называю свои строки «зебра» «row0» и «row1» - это немного упрощает код.
<?php // you should always use the full opening tag for compatibility
$i = 0;
foreach ($rows as $row) {
echo '<tr class = "row' . ($i++ % 2) . '">...</tr>';
}
?>
Ух ты! Это кажется самым коротким!
@thrashr: если у вас foreach ($rows as $i => $row), вы можете удалить $i = 0. Но все это зависит от получения ваших строк в виде массива, прежде чем вы сможете использовать их с помощью foreach.
function row_color($cnt,$even,$odd) {
echo ($cnt%2) ? "<tr bgcolor=\"$odd\">" : "<tr bgcolor=\"$even\">";
}
Как использовать:
$cnt=0;
while ($row = mysql_fetch_array ($result)) {
row_color($cnt++,"e0e0e0","FFFFFF");
}
Простая маленькая функция, которая мне подходит.
<?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>
Но не короче и не легче! Но я думаю, это работает достаточно хорошо.
Вы можете использовать область $ GLOBAL для хранения текущего выбранного состояния класса, см. Ниже функцию table_row_toggle (). Да, я знаю, что злоупотреблять областью действия $ GLOBAL грязно, но мы здесь, чтобы исправить проблемы, не так ли? :)
Вызов функции переключения строк таблицы в HTML:
<tr <? table_row_toggle(); ?>>
Функция в 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.'">';
В PHP я использую этот код:
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
*/
Источник: http://sklueh.de/2013/11/einfache-alternierung-mit-php/
Место на Vilx, но всегда старайтесь минимизировать скорость (вес страницы)
<tr class = "'.(($c = !$c)?'odd':'even').'">
Пожалуйста, не используйте короткие открытые теги (например, <?) - он не переносится во всех конфигурациях.