Php 建议实现这一目标的另一种方法;字栈;它解决了我的方法所面临的已知问题

Php 建议实现这一目标的另一种方法;字栈;它解决了我的方法所面临的已知问题,php,javascript,css,overflow,Php,Javascript,Css,Overflow,我试图在两个标签的堆栈中转换一组两个单选按钮,一个蓝色,一个灰色,分别表示选中的单选按钮和未选中的单选按钮。单击此堆栈将更改哪些标签为蓝色(以及选中了哪些单选按钮)。它工作得很好,但当两个标签的宽度不一样时,它会以一种丑陋的方式崩溃。了解我的意思的最好方法是尝试在您自己的服务器上制作的测试页面,或者导航以查看正在运行的页面 源代码和实际内容中的注释基本上解释了我的目标和问题所在。此外,这是一种尝试,旨在实现无障碍性和优雅的降级,因此任何关于这些问题的评论都是非常受欢迎的 <!DOCTYPE

我试图在两个标签的堆栈中转换一组两个单选按钮,一个蓝色,一个灰色,分别表示选中的单选按钮和未选中的单选按钮。单击此堆栈将更改哪些标签为蓝色(以及选中了哪些单选按钮)。它工作得很好,但当两个标签的宽度不一样时,它会以一种丑陋的方式崩溃。了解我的意思的最好方法是尝试在您自己的服务器上制作的测试页面,或者导航以查看正在运行的页面

源代码和实际内容中的注释基本上解释了我的目标和问题所在。此外,这是一种尝试,旨在实现无障碍性和优雅的降级,因此任何关于这些问题的评论都是非常受欢迎的

<!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;
                    </pre>
                </code>
            </li>
            <li>
                javascript hides the radio buttons, applies class declarations to the labels and adds an onclick event listener to the<br />
                <code>
                    &lt;span class="stack"&gt;
                </code>
            </li>
        </ol>

        <h2 id="example">Example</h2>
        <form action="<?php echo($_SERVER['PHP_SELF'] . "#example"); ?>" class="stackContainer" method="post">
            <p>Choose between <?php createWordStack("name","one","two"); ?> options.</p>
            <input type="submit" value="Test that the radio buttons hidden behind this still work" />
        </form>
        <h3>print_r($_POST)</h3>
        <pre>
            <?php print_r($_POST); ?>
        </pre>

        <form class="stackContainer">
            <h2>Known issues</h2>
            <p>
                This technique
                <?php createWordStack("no_matter","absolutely does not","does"); ?>
                look good with two different sizes of `words`,
                <?php createWordStack("no_matter2","no matter","although this depends"); ?>
                in which order they appear. If looks better when the longer word is above the other though. Plus, the way it breaks makes it unreadable when the longer word is on the bottom if the remainder of the text needs to span many lines.
            </p>
            <p>
                Another problem is when the bottom word
                <?php createWordStack("no_matter3","is","isn't"); ?>
                longer than the top word but actually consists of a single word. It cannot wrap and therefore interferes with the following text.
            </p>

            <p>
                <?php createWordStack("no_matter4","It really becomes unusable and quite ugly if the top word happens to wrap and span over two or more lines. Of course, the first know issue shown above is enough to understand that THIS known issue doesn't mean a thing if it is the bottom that is too long as it will span over many lines no matter what since it is limited by the width of the shorter word above..","It still works"); ?>
                .. and so, all in all, it is better to avoid long words altogether.
            </p>
            <p>
                Now, just to illustrate what I am saying above.. 
                <?php createWordStack("no_matter5","Look at this shit!","It really becomes unusable and quite ugly if the top word happens to wrap and span over two or more lines. Of course, the first know issue shown above is enough to understand that THIS known issue doesn't mean a thing if it is the bottom that is too long as it will span over many lines no matter what since it is limited by the width of the shorter word above.."); ?>
                .. and so, all in all, it is better to avoid long words altogether.
            </p>
            <h2>Notes</h2>
            <p>
                At least, the next paragraph
                <?php createWordStack("no_matter6","isn't","is"); ?>
                pushed down too far.
            </p>
            <p>
                <?php createWordStack("no_matter7","It works","It doesn't work"); ?>
                when I put the stackBottom BEFORE the stackTop, so I could also call them stackChosen and stackAlternate and just change the className in order to choose one or the other. This is what the javascript used to do when you click on the stack: if the label is of class stackTop, it changes it to stackBottom, and vice-versa. Now, only the colour is changed..
            </p>
        </form>
    </body>
</html>
  • javascript隐藏单选按钮,将类声明应用于标签,并将onclick事件侦听器添加到
    
    span class=“stack”
    
  • 例子
    为堆栈底部使用position absolute打破了一切(浏览器无法将堆栈底部宽度考虑在内),这里有一种替代方法,使用inline bock

    将.stack、.stackTop和.stackBottom定义替换为以下内容:


    缺少Doctype是一个问题。比较quirks模式下的测试页面和标准模式下的真实页面没有任何意义:/Understand,我在中添加了doctype和定义字符集的元类型。还有别的吗?哦,顺便说一句,这些并没有改变任何事情。我认为你不可能发现很多人在不知道他们在寻找什么的情况下愿意阅读这么长时间的剧本。与其说“重新整理我的脚本并告诉我如何修复它”,我建议列出错误并寻求解决方案(或为不同的问题创建不同的问题)。当然,你是对的,但我发现很难向看不到问题的人解释问题。最简单的方法是将页面添加到您自己的服务器并打开它。在这一页中,我解释了它是如何工作的,我展示了它工作正常时的样子,我展示了它断裂时的样子。检查的时间真的不长,你只需要将它添加到你的www文件夹并打开它。。不过,我会尝试在实际问题中解释问题。谢谢我的两分钱:别这样。你不应该试图用点击时跳转到另一个位置的元素来创建你自己的用户界面。这些元素真的应该留在同一个地方。它让我想起了非常好的。它似乎对Firefox和Epiphany有效。你手头还有其他浏览器可以测试吗?适用于基于webkit的浏览器(safari+chrome),应该适用于IEI的最新版本。我从其他人那里得知,它确实适用于MSIE7。如果有人能测试Opera,这将以优异的成绩通过!你担心旧版本的IE吗?我知道IE6不支持内联块,但别担心opera,这会有用的。虽然不是我的最爱,但它仍然是一款很棒的浏览器
    .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 */
    }