一段jquery代码无法在Internet Explorer中工作

时间:2012-12-24 22:55:24

标签: php jquery html

我在下面有一段代码,其中显示了2个下拉菜单,一个用于建筑物,另一个用于房间。当用户从其下拉菜单中选择一个建筑物时,它将使用ajax导航到room.php,在该脚本中,它编译一个查询并输出一个房间列表,然后在房间下拉菜单中显示页:

         $sql = "SELECT DISTINCT Building FROM Room"; 

 $sqlstmt=$mysqli->prepare($sql);

 $sqlstmt->execute(); 

 $sqlstmt->bind_result($dbBuilding);

 $buildings = array(); // easier if you don't use generic names for data 

 $buildingHTML = "";  
 $buildingHTML .= '<select name="buildings" id="buildingsDrop" onchange="getRooms();">'.PHP_EOL; 
 $buildingHTML .= '<option value="">Please Select</option>'.PHP_EOL;  

 while($sqlstmt->fetch()) 
 { 
     $building = $dbBuilding; 
     $buildingHTML .= "<option value='".$building."'>" . $building . "</option>".PHP_EOL;  
  } 

  $buildingHTML .= '</select>'; 

  $roomHTML = "";  
  $roomHTML .= '<select name="rooms" id="roomsDrop">'.PHP_EOL; 
  $roomHTML .= '<option value="">Please Select</option>'.PHP_EOL;  
  $roomHTML .= '</select>'; 


        ?>

<script type="text/javascript">

        function getRooms() { 
    var building = jQuery("#buildingsDrop").val(); 
    jQuery('#roomsDrop').empty(); 
    jQuery('#roomsDrop').html('<option value="">Please Select</option>'); 
    jQuery.ajax({ 
          type: "post", 
          url:  "room.php", 
          data: { building:building }, 
          success: function(response){ 
              jQuery('#roomsDrop').append(response); 
          } 
        }); 


 }

 </script> 

现在上面的代码适用于除Internet Explorer之外的所有浏览器。感谢一些关于SO的好建议我被告知要验证脚本,因为Internet Explorer在验证代码方面非常严格。

无论如何,在我的验证中,我意识到我有这个错误:

  

文档类型不允许元素“选项”在这里:

指向以下这一行:

jQuery('#roomsDrop').html('<option value="">Please Select</option>'); 

它声明它需要进入<select>标签,我在技术上试图在上面的代码中做。我的问题是如何修复代码以通过验证,但是能够执行它所做的工作,从建筑物下拉菜单中选择建筑物后,在房间下拉菜单中显示房间列表?

以下是应用程序,请在Internet Explorer中打开应用程序,也可以在chrome,firefox,opera或safrai中打开。首先在其中一个非Internet浏览器浏览器中显示应用程序以查看应用程序的工作方式,然后在Internet Explorer中进行测试,您可以自己查看问题以及我想要实现的目标。

Application (Please open in Internet Explorer and in one other major browser)

更新:

<!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>Room </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="roomStyle.css">
</head>



<body>

<?php

     // connect to the database
 include('connect.php');

 /* check connection */
 if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}


$building = isset($_POST['building']) ? $_POST['building'] : ''; 

$sql = "SELECT Room FROM Room WHERE Building = ?"; 

 $sqlstmt=$mysqli->prepare($sql);

 $sqlstmt->bind_param("s",$building);

 $sqlstmt->execute(); 

 $sqlstmt->bind_result($dbRoom);


$roomHTML  = "";  

 while($sqlstmt->fetch()) { 
    $roomHTML .= "<option value='".$dbRoom."'>" . $dbRoom . "</option>".PHP_EOL;  
} 


echo $roomHTML; 

 $sqlstmt->execute(); 


?>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

问题是room.php正在返回:

<!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>Room </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="roomStyle.css">
</head>



<body>

<option value='CW2/08'>CW2/08</option>
<option value='CW4/09'>CW4/09</option>
<option value='CW4/10'>CW4/10</option>
<option value='CW5/10'>CW5/10</option>
</body>
</html>

什么时候应该只返回这个(基于你如何使用响应):

<option value='CW2/08'>CW2/08</option>
<option value='CW4/09'>CW4/09</option>
<option value='CW4/10'>CW4/10</option>
<option value='CW5/10'>CW5/10</option>

虽然我不愿意这么说,但Internet Explorer是正确的(在这种情况下)。 <option>元素不应该是<body>元素的直接子元素。

这在Chrome中运行的原因(例如)Chrome只会将其附加到select#roomDrop

<title>Room </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="roomStyle.css">
<option value="CW2/08">CW2/08</option>
<option value="CW4/09">CW4/09</option>
<option value="CW4/10">CW4/10</option>
<option value="CW5/10">CW5/10</option>

并且Chrome无法直观呈现<title>元素中的<meta><link><select>元素。

至少有几种方法可以解决这个问题。

  1. room.php更改为仅输出<option>元素。
  2. getRooms()功能更改为仅附加返回的<option>元素。
  3. 至于上面两个修正中的哪一个,它将取决于您使用room.php的其他内容。还有其他解决方案(我确定),但最终将归结为修复PHP或修复AJAX调用。

    没有看到room.php的PHP源代码,我无法帮助解决第一个问题。第二种可以这样做:

    function getRooms() {
        'use strict';
        var building = jQuery("#buildingsDrop").val(),
            //use jQuery (or plain JavaScript) to build the option as a DOM element
            defaultOption = $('<option />').text('Please Select').val('');
        //append the DOM element, not an HTML string
        jQuery('#roomsDrop').empty().append(defaultOption);
        jQuery.ajax({
            "type": "post",
            "url": "room.php",
            "data": {
                "building": building
            },
            "success": function (response) {
                //filter out the option elements
                var opts = $(response).filter('option');
                //and append only those
                jQuery('#roomsDrop').append(opts);
            },
            "error": function (jqXHR, textStatus, errorThrown) {
                //always good to have an error handler.
                console.log(textStatus);
                console.log(errorThrown);
            }
        });
    }
    

    您可能会注意到我使用jQuery将初始选项构建为DOM元素,而不是构建HTML字符串。我这样做是因为:

    1. 通常认为这是一种更好的做法。
    2. 它消除了通过字符串连接构建元素的需要。
    3. 它使我不必编写格式良好的HTML(在长字符串上可能很难)。
    4. 不需要付出太多努力。
    5. <强>更新

      由于您已包含room.php的PHP源代码,因此您可以将其修改为仅输出<option>元素,如下所示:

      <?php
          // connect to the database
          include('connect.php');
          /* check connection */
          if (mysqli_connect_errno()) {
              printf("Connect failed: %s\n", mysqli_connect_error());
              die();
          }
          $building = isset($_POST['building']) ? $_POST['building'] : '';
      
          $sql = "SELECT Room FROM Room WHERE Building = ?";
          $sqlstmt=$mysqli->prepare($sql);
          $sqlstmt->bind_param("s",$building);
          $sqlstmt->execute();
          $sqlstmt->bind_result($dbRoom);
      
          $roomHTML  = "";
      
          while($sqlstmt->fetch()) {
              $roomHTML .= "<option value='".$dbRoom."'>" . $dbRoom . "</option>".PHP_EOL;
          }
          echo $roomHTML;
          $sqlstmt->execute();
      ?>
      

      也就是说,简单地删除与<option>元素无关的所有内容。