函数名称根据onchange id动态更改

时间:2013-10-08 17:41:27

标签: javascript php

我正在尝试制作表格,简单吧?不太好。

我目前的表单设置有两个选择框,第一个选择在使用onchange函数更改时会运行一个生成第二个选择框的php页面。

然后我有另一个函数添加了2个选择框的另一个'实例',这样我就可以一次向表中添加多行,而不必一次输入一行。

当我添加更多'实例'时出现问题,onchange函数将第二个选择框的原始和新“实例”视为同一个。

我可以看到我最好的选择是动态命名函数和包含第二个选择框的div,这就是我被卡住的地方。我的问题是,如何更改'showDim'功能和'dimdiv'div id以便它们匹配?

js函数调用Dim选择框;

<script>
    function showDim(str)
    {
    if (str=="")
      {
      document.getElementById("dimdiv").innerHTML="";
      return;
      } 
    if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
        document.getElementById("dimdiv").innerHTML=xmlhttp.responseText;
        }
      }
    xmlhttp.open("GET","get_dim.php?id="+str,true);
    xmlhttp.send();
    }
</script>

html / php为第一个选择框和div包含第二个选择框; (另一个函数根据我的需要复制这部分次数)

<label>Style:</label>
    <select name='Style' id='Style' onchange="showDim(this.value)">
        <option value='0' class='red'>Select a style...</option>            
        <?php
            include ('connect.php');

            $getsty = $db->prepare("SELECT Style_ID, Style_Type FROM style ORDER BY Style_Type ASC LIMIT 1, 18446744073709551615;"); 
            $getsty->execute();
                while($row = $getsty->fetch(PDO::FETCH_ASSOC)) {    
                    $Style_ID = $row['Style_ID'];
                    $Style_Type = $row['Style_Type'];                   
                    echo "      <option value='$Style_ID'>$Style_Type</option>";
                }                                       
        ?>                          
<br>
<div id='txtHint2'>                 
    <label>Dimensions:</label>
        <select name='Dim'>
            <option value='0' class='red'>Select the dimensions...</option> 
        </select>           
</div>

1 个答案:

答案 0 :(得分:1)

我会使用完全不同的方法。我没有看到ID为#dimdiv的元素在哪里,但是在“实例”周围创建一个包装器以对其进行分组,包括#dimdiv。但现在所有的ID都应该是类。

您的HTML应如下所示:

<div class="instance">
    <label>Style:</label>
        <select name='Style' class='style' onchange="showDim(this)">
            <option value='0' class='red'>Select a style...</option>            
            <?php
                include ('connect.php');

                $getsty = $db->prepare("SELECT Style_ID, Style_Type FROM style ORDER BY Style_Type ASC LIMIT 1, 18446744073709551615;"); 
                $getsty->execute();
                    while($row = $getsty->fetch(PDO::FETCH_ASSOC)) {    
                        $Style_ID = $row['Style_ID'];
                        $Style_Type = $row['Style_Type'];                   
                        echo "      <option value='$Style_ID'>$Style_Type</option>";
                    }                                       
            ?>                          
    <!-- Note: for proper HTML markup, a non-container tag must be self-closing like the following br -->
    <br />
    <div class='txtHint2'>
        <label>Dimensions:</label>
            <select name='Dim'>
                <option value='0' class='red'>Select the dimensions...</option> 
            </select>           
    </div>
    <div class="dimdiv"></div>
</div>

显然这会破坏您当前的代码。您无法使用document.getElementById('dimdiv')查找要设置 innerHTML 的元素。所以我们需要改进你的代码...

第一步:我们需要知道调用showDim函数的组号。这是最简单的方法,不仅要将元素的值传递给函数,还要传递元素本身。它允许我们使用document.getElementsByClassName('style') * 1并将每个返回的元素与当前元素进行比较。

第一个匹配是实例组的索引,我们现在可以使用类似的方法来提取同一组的相应.dimdiv。所以现在我们已经找到了我们的目标元素,而不需要创建单个函数的多个实例,这在我眼中是有缺陷的设计......它会让人记忆深刻。

您更改的代码可能如下所示:

HTML

<select name="Style" class="style" onchange="showDim(this)">
    ...
</select>

JavaScript (已编辑)

function showDim(elem)
{
    // Best would be to pack this code into a separate function.
    var elems = document.getElementsByClassName('style'),
        groupIndex = -1,
        targetDimDiv,
        i;
    for( i = 0; i < elems.length; ++i ) {
        if( elems[i] == elem ) {
            groupIndex = i;
            break;
        }
    }

    // This can only happen if somebody plays around with your function
    // manually calling it and providing an unexpected parameter.
    if( groupIndex == -1 )
    {
        return;
    }

    targetDimDiv = document.getElementsByClassName('dimdiv')[groupIndex];

    if (elem.value == "")
    {
        targetDimDiv.innerHTML="";
        return;
    }
    // ...XMLHttpRequest...
    xmlhttp.onreadystatechange = function( ) {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
            targetDimDiv.innerHTML = xmlhttp.responseText;
        }
    };
    // ...send AJAX...
}

最后,我要说明最后一个关键点:我不认为为每次价值变化创建一个ajax是个好主意。我认为最好已经通过网站提供回复并从那里检索您需要的信息。它会在以后节省更多的流量......

对于冗长的回答感到抱歉,但我认为真正理解为什么代码的工作方式非常重要。我怀疑你可能不是那么经历过的事情......;)

* 1:我相信在早期版本的IE中不存在document.getElementsByClassName。如果必须支持这些版本,可以手动使用document.getElementsByTagName匹配类编写补丁。

P.S。:尚未测试代码。它只是为您提供通用指南。剩下的由你决定。摆弄它以满足您的需求。