Я пытаюсь преобразовать набор из двух радиокнопок в стопку из двух меток, одна из которых синего и серого цвета, обозначающая, соответственно, выбранное радио и невыбранное.Нажатие на этот стек изменяет, какая из меток синего цвета (и какая из переключателей отмечена).Это работает хорошо, но уродливо ломается, когда две метки не имеют одинаковую ширину.Лучший способ понять, что я имею в виду, - это попробовать тестовую страницу, которую я создал, на вашем собственном сервере или перейти по здесь , чтобы увидеть страницу в действии.
Комментарии в исходном кодеи фактическое содержание объясняет в значительной степени то, к чему я стремлюсь и какие проблемы.Кроме того, это попытка доступности и постепенного ухудшения, поэтому любые замечания, касающиеся этих проблем, приветствуются.
<code><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>word stacks</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
.stackContainer
{
line-height: 2em; /* Prevents the stackBottom from overlaping the second line of text found in the stack container, should there be a second line. */
}
.stack
{
position: relative; /* Needed to give the absolutely positionned stackBottom a positionned reference. */
}
.stackTop
{
vertical-align: .5em; /* Raise the stackTop half a line */
}
.stackBottom
{
background: transparent; /* Needed so the background doesn't cover the stackTop nor the line below, if any. */
position: absolute; /* Positionned absolutely in reference to the stack */
left: 0; /* Bring the stackBottom directly under the stackTop */
top: 0; /* For some reason, this is needed to bring the stackBottom under the stackTop. */
}
/* The following is extra */
.stackSelected /* Represents the chosen value */
{
color: #009;
}
.stackUnselected /* Represents the other option */
{
color: #777;
}
.stack
{
cursor: pointer;
}
p
{
margin: 3em;
}
</style>
<?php
function createWordStack($name, $value1, $value2)
{
// Set default values (by default, $value1 is checked and not $value2)
$firstChecked = "checked=\"checked\" ";
$secondChecked = "";
if(isset($_POST[$name])) // One value was chosen
{
if($_POST[$name] == $value2) // Not default value
{
$firstChecked = "";
$secondChecked = "checked=\"checked\" ";
}
// else fall back to default value
}
// else fall back to default value
// Write out the html
echo("<span class=\"stack\">
<label for=\"" . $name . "\">
<input type=\"radio\" name=\"" . $name . "\" value=\"" . $value1 . "\" " . $firstChecked . "/>" . $value1 . "
</label>
<label for=\"" . $name . "\">
<input type=\"radio\" name=\"" . $name . "\" value=\"" . $value2 . "\" " . $secondChecked . "/>" . $value2 . "
</label>
</span>");
}
?>
<script type="text/javascript">
// It is recommended to use this function only if stacks have been created with the php function createStack and if these stacks are contained in an element of class stackContainer
function makeStacks()
{
var forms = document.getElementsByTagName("form"); // Find all forms
var nb_forms = forms.length;
for(var i = 0; i < nb_forms; ++i)
{
if(forms[i].className.indexOf("stackContainer") != -1) // If it's a stackContainer
{
var spans = forms[i].getElementsByTagName("span"); // Find all spans
var nb_spans = spans.length;
for(var j = 0; j < nb_spans; ++j)
{
if(spans[j].className.indexOf("stack") != -1) // If it's a stack
{
var labels = spans[j].getElementsByTagName("label"); // Find all labels
var nb_labels = labels.length;
if(nb_labels == 2) // Only works with two labels!
{
labels[0].className += " stackTop";
labels[1].className += " stackBottom";
for(var k = 0; k < nb_labels; ++k)
{
var inputs = labels[k].getElementsByTagName("input"); // Find all inputs
var nb_inputs = inputs.length;
if(nb_inputs == 1 && inputs[0].type == "radio") // Only works with one radio button per label!
{
inputs[0].style.display = "none"; // Hide radio button
labels[k].className += (inputs[0].checked)?" stackSelected":" stackUnselected";
}
}
}
// add onclick listener to invert which radio button is checked and invert which label appears on top
spans[j].onclick = function()
{
var labels = this.getElementsByTagName("label"); // Find all labels
// We already know that there are only two labels, from earlier!
for(var l = 0; l < 2; ++l)
{
// Invert className from stackTop to stackBottom (or vice-versa)
if(labels[l].className.match(/stackSelected/))
{
labels[l].className = labels[l].className.replace(/stackSelected/, "stackUnselected");
}
else if(labels[l].className.match(/stackUnselected/))
{
labels[l].className = labels[l].className.replace(/stackUnselected/, "stackSelected");
}
}
// Change which of the radios is checked
var inputs = labels[0].getElementsByTagName("input"); // Find all inputs from first label
// We already know that there is a single label and that it is a radio, from earlier!
if(!inputs[0].checked) // If this one is not checked, check it to change which of the radios is checked
{
inputs[0].checked = true;
}
else
{
var inputs = labels[1].getElementsByTagName("input"); // Find all inputs from second label
// We already know that there is a single label and that it is a radio, from earlier!
if(!inputs[0].checked) // If this one is not checked, check it to change which of the radios is checked
{
inputs[0].checked = true;
}
// else there is something wrong as none of the radios are checked!
}
}
}
}
}
}
}
window.onload = makeStacks;
</script>
</head>
<body>
<h1>Word stacks</h1>
<h2>How it works</h2>
<ol>
<li>PHP transforms<br />
<code><?php createWordStack("name","one","two"); ?></code><br />
into<br />
<code>
<pre>
<span class="stack">
<label for="name">
<input type="radio" name="name" value="one" />one
</label>
<label for="name">
<input type="radio" name="name" value="two" checked="checked" />two
</label>
</span>
javascript скрывает переключатели, применяет объявления классов к меткам идобавляет слушателя события onclick к
<span class="stack">
Пример "class =" stackContainer "method =" post ">
Выберите междуопции.
Проверьте, что скрытые за этим переключатели все еще работают
print_r ($ _ POST)
<?php print_r($_POST); ?>
Известные проблемы
Эта техникахорошо смотрятся с двумя разными размерами слов,в каком порядке они появляются.Если выглядит лучше, когда длинное слово выше другого, хотя.Кроме того, то, как он разрывается, делает его нечитаемым, когда длинное слово находится внизу, если остальная часть текста должна занимать много строк.
Другая проблема, когда нижнее словодлиннее верхнего слова, но на самом деле состоит из одного слова.Он не может переноситься и поэтому мешает следующему тексту.
.. и так, в общем, лучше вообще избегать длинных слов.
Теперь, просто чтобы проиллюстрировать то, что я говорю выше .... и так, в общем, лучше вообще избегать длинных слов.
Примечания
Как минимум, следующий абзацтолкнул слишком далеко.
когда я помещаю stackBottom перед stackTop, чтобы я мог также вызывать их stackChosen и stackAlternate и просто изменить className для выбора одного или другого.Это то, что делал javascript, когда вы щелкаете по стеку: если метка имеет класс stackTop, она меняет его на stackBottom и наоборот.Теперь изменился только цвет ..
Итак, вопрос: как мне решить известные проблемы, описанные на тестовой странице?Извините, я знаю, что это не способ задать вопрос, но я просто не знаю, как еще это сформулировать.Я приложил много усилий, чтобы сделать эту тестовую страницу как можно более четкой.
Заранее спасибо