如何为每个帖子添加一个eventListener(不使用jQuery)?

时间:2018-09-12 07:44:09

标签: javascript php mysql ajax

我正在编写一个代码,用户可以在其中获取帖子标题列表中的用户帖子。如果用户单击帖子标题,则应显示一个包含更多信息的新div框。帖子使用php获取,而帖子说明将通过AJAX获取。 (稍后我还将使用AJAX获取帖子)

我的问题:只有第一个帖子标题有效,并且通过单击它,所有帖子描述都会显示在1 div框中。我认为我需要一个数组,并且尝试失败。

它应该做什么:例如,通过单击标题:2,仅应显示帖子2的描述。
请记住,帖子标题列表是动态的,是从数据库中获取的数据。

这是我的代码:

INDEX.PHP

<!DOCTYPE html>
<html>
  <head>
    <title>XY</title>
    <meta charset="UTF-8"/>
  </head>

  <body>
    <?php
    $db = mysqli_connect("localhost", "root", "", "xy");
    $result = mysqli_query($db, "SELECT * FROM images");
      while ($row = mysqli_fetch_array($result))
      {
          echo "<div class='img_title'><button id='img_descr'><a>Title: <b>".$row['img_title']."</b></a></button></div>";
      }
    ?>
    <div id="descrs"></div>
    <script>
      document.getElementById('img_descr').addEventListener('click', loadDescr);

      function loadDescr(){
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'ajax.php', true);

        xhr.onload = function(){
          if(this.status == 200){
            var descrs = JSON.parse(this.responseText);

            var output = '';

            for(var i in descrs){
              output += '<ul>' +
                '<li class="ajax_img_descr">ID: '+descrs[i].img_descr+'</li>' +
                '</ul>';
            }
            document.getElementById('descrs').innerHTML = output;
          }
        }
        xhr.send();
      }
    </script>
  </body>
</html>

AJAX.PHP

<?php
// Create Connection
$conn = mysqli_connect('localhost', 'root', '', 'xy');
$query = 'SELECT * FROM images';
// Get Result
$result = mysqli_query($conn, $query);
// Fetch Data
$users = mysqli_fetch_all($result, MYSQLI_ASSOC);
echo json_encode($users);
?>

数据库结构/内容:

  1. 创建一个名为“ xy”的数据库
  2. 创建一个名为“ images”的表:

    CREATE TABLE images (
        img_id int(11) not null AUTO_INCREMENT PRIMARY KEY,
        img_file varchar(250) not null,
        img_title text(50) not null,
        img_descr varchar(250) not null
    );
    
  3. 将数据插入数据库:

    INSERT INTO images (img_title, img_descr) VALUES ('Golden Retriever', 'UK:DFYDFBAERSDFBYDFBYDFydfbydfBaeydfb1311y');
    INSERT INTO images (img_title, img_descr) VALUES ('Appenzeller Sennenhund', 'Swiss:erydfydfbrehaydydfbydfydbaerydf2ydfb');
    INSERT INTO images (img_title, img_descr) VALUES ('German Shepard', 'Germany:ydf3d1fby3df1by3dfb6ydfb31ydf31ydf');
    INSERT INTO images (img_title, img_descr) VALUES ('Alaskan Klee Kai', 'USA:f3ngxfgxfgnxfxfgnxfg3xf31gnxfgner6ae13')
    

1 个答案:

答案 0 :(得分:2)

您对所有按钮使用相同的ID img_descr这就是为什么它仅对第一个按钮的事件有效,而对其他按钮不起作用的原因。

尝试为这些按钮或唯一ID使用类。下面是对这些按钮使用通用类的示例。 document.querySelectorAll将返回所有类为“ img_descr”的按钮作为NodeList(DOM节点列表),它是一种数组类型,您可以使用循环对其进行迭代。您可以使用CSS选择器。(dot)class /#for( id)。

这里是示例,它可以在我的电脑上运行。希望它也对您有用!

<!DOCTYPE html>
<html>
  <head>
    <title>XY</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <?php
       $db     = mysqli_connect("localhost", "root", "", "xy");
       $result = mysqli_query($db, "SELECT * FROM images");
       while ($row = mysqli_fetch_array($result)) {
          // changed <button id='img_descr'> to <button class='img_descr'>
          echo "<div class='img_title'><button class='img_descr'><a>Title: <b>" . $row['img_title'] . "</b></a></button></div>";
       }
     ?>
     <div id="descrs"></div>
     <script>
       // Get the buttons (NodeList)
       var buttons = document.querySelectorAll("button.img_descr"); 
       console.log(buttons); // debugging in JS!! press F12, see console tab!

       for(var x=0; x < buttons.length; x++) {
         buttons[x].addEventListener('click', loadDescr);
       }

       // getElementById returns only one element with the id passed as input
       // which is the first found node with the id in the DOM.
       // document.getElementById('img_descr').addEventListener('click', loadDescr);

     function loadDescr(e) {
        // here e is the event and you can get the source of the event(button) by
        // e.target target. Here target would be the button that you clicked.
        console.log(e.target.innerHTML); // use console.log() very often in JS code!
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'ajax.php', true);

        xhr.onload = function() {
           if (this.status == 200) {
             var descrs = JSON.parse(this.responseText);

             var output = '';

             for (var i in descrs) {
               output += '<ul>' +
                   '<li class="ajax_img_descr">ID: ' + descrs[i].img_descr + '</li>' +  '</ul>';
             }
             document.getElementById('descrs').innerHTML = output;
         }
       }
       xhr.send();
     }
    </script>
  </body>
</html>

更新

问题1:我是否必须使用“ img_id”来实现这一目标?您是否要为此提出一个新问题?

Ans1: ID对于所有元素都应该始终是唯一的。通过ID,您可以唯一地标识DOM中的节点。您可以使用数据库中的img_id作为主键。

第二季度:通过单击任意按钮,所有描述都一起显示。我需要的是:     点击标题1->获取描述1,     单击标题2->获取说明2,依此类推,以此类推,标题列表将被动态加载

Ans2:您可以使用此方法执行此操作,尽管有多种方法可以执行此操作:

// 1.1 PHP Change
while ($row = mysqli_fetch_array($result)) {
  // changed <button id='img_descr'> to <button class='img_descr' id=row's id column>
  echo "<div class='img_title'><button class='img_descr' id="$row['id']"><a>Title: <b>" . $row['img_title'] . "</b></a></button></div>";
}

// 1.2 JS change
function loadDescr(e) {
     ...
     console.log(e.target.innerHTML); // use console.log() very often in JS code!
     let id = e.target.getAttribute('id'); // get the ID of element, e.target.id also does the same 
     var xhr = new XMLHttpRequest();
     xhr.open('GET', 'ajax.php?img='+id, true); // append the id in query
     ...
 }

// 1.3 PHP ajax.php change

// check if the query has id passed
if (isset($_GET['img'])) {
    $id = $_GET['img'];
    // change the query to find by id
    $query = "SELECT * from images where img_id=$id";
} else {
    $query = "SELECT * from images";
}
$result = mysqli_query($conn, $query);
// Fetch Data
$users = mysqli_fetch_all($result, MYSQLI_ASSOC);
echo json_encode($users);

希望这会有所帮助!