Предложите другой метод достижения этого «стека слов», который решает известные проблемы, жертвами которых является мой метод - PullRequest
0 голосов
/ 22 июня 2010

Я пытаюсь преобразовать набор из двух радиокнопок в стопку из двух меток, одна из которых синего и серого цвета, обозначающая, соответственно, выбранное радио и невыбранное.Нажатие на этот стек изменяет, какая из меток синего цвета (и какая из переключателей отмечена).Это работает хорошо, но уродливо ломается, когда две метки не имеют одинаковую ширину.Лучший способ понять, что я имею в виду, - это попробовать тестовую страницу, которую я создал, на вашем собственном сервере или перейти по здесь , чтобы увидеть страницу в действии.

Комментарии в исходном кодеи фактическое содержание объясняет в значительной степени то, к чему я стремлюсь и какие проблемы.Кроме того, это попытка доступности и постепенного ухудшения, поэтому любые замечания, касающиеся этих проблем, приветствуются.

<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>&lt;?php createWordStack("name","one","two"); ?&gt</code><br />
                into<br />
                <code>
                    <pre>
&lt;span class="stack"&gt;
    &lt;label for="name"&gt;
        &lt;input type="radio" name="name" value="one" /&gt;one
    &lt;/label&gt;

    &lt;label for="name"&gt;
        &lt;input type="radio" name="name" value="two" checked="checked" /&gt;two
    &lt;/label&gt;
&lt;/span&gt;
                    
javascript скрывает переключатели, применяет объявления классов к меткам идобавляет слушателя события onclick к &lt;span class="stack"&gt; Пример "class =" stackContainer "method =" post ">

Выберите междуопции.

Проверьте, что скрытые за этим переключатели все еще работают

print_r ($ _ POST)

            <?php print_r($_POST); ?>
        

Известные проблемы

Эта техникахорошо смотрятся с двумя разными размерами слов,в каком порядке они появляются.Если выглядит лучше, когда длинное слово выше другого, хотя.Кроме того, то, как он разрывается, делает его нечитаемым, когда длинное слово находится внизу, если остальная часть текста должна занимать много строк.

Другая проблема, когда нижнее словодлиннее верхнего слова, но на самом деле состоит из одного слова.Он не может переноситься и поэтому мешает следующему тексту.

.. и так, в общем, лучше вообще избегать длинных слов.

Теперь, просто чтобы проиллюстрировать то, что я говорю выше .... и так, в общем, лучше вообще избегать длинных слов.

Примечания

Как минимум, следующий абзацтолкнул слишком далеко.

когда я помещаю stackBottom перед stackTop, чтобы я мог также вызывать их stackChosen и stackAlternate и просто изменить className для выбора одного или другого.Это то, что делал javascript, когда вы щелкаете по стеку: если метка имеет класс stackTop, она меняет его на stackBottom и наоборот.Теперь изменился только цвет ..

Итак, вопрос: как мне решить известные проблемы, описанные на тестовой странице?Извините, я знаю, что это не способ задать вопрос, но я просто не знаю, как еще это сформулировать.Я приложил много усилий, чтобы сделать эту тестовую страницу как можно более четкой.

Заранее спасибо

1 Ответ

1 голос
/ 23 июня 2010

Использование абсолютного положения для вашего дна стека сломало все (браузер не мог учесть ширину дна стека), здесь альтернатива использует вместо этого inline-bock

Замените ваши определения .stack, .stackTop и .stackBottom следующим:

.stack{
  display: inline-block; /* prevent the block options to induce line breaks in your text */
  line-height: 1; /* Have the 2 options verticaly close to each other */
  position: relative; /* Moves the lines to be in between*/
  top: 0.5em;
  white-space: nowrap; /* prevent line breaks */
}

.stackTop,
.stackBottom{
  display: block; /* Stack the options on top of each other */
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...