卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章16549本站已运行3318

使用 jQuery、AJAX 和 PHP 构建 5 星级评级系统

使用 jQuery、AJAX 和 PHP 构建 5 星级评级系统

网站上的星级评级系统使用户可以轻松提供反馈并帮助其他人做出选择。它为企业提供有关客户如何喜欢其产品的反馈。星级评级还有助于建立对网站及其产品的信任。

所有主要电子商务网站都使用评级来让买家了解他们对产品的期望质量。

在本教程中,我将向您展示如何构建自己的五星级评级系统。

为结构编写 HTML 和 CSS

构建星级评级系统过程的第一步是编写标记,这取决于我们想要在页面上显示的元素。

我们绝对希望将电影的名称包含在我们的评级小部件中。我们还需要在小部件内显示五颗星,用户可以单击这些星来投票。用户投票后,我们还将向他们显示投票数据。

以下 HTML 实现了这一切:

<div class="rating-wrapper" data-id="raiders">
  <h2>Raiders of the Lost Ark</h2>
  <div class="star-wrapper">
    <i class="fa-regular fa-star"></i>
    <i class="fa-regular fa-star"></i>
    <i class="fa-regular fa-star"></i>
    <i class="fa-regular fa-star"></i>
    <i class="fa-regular fa-star"></i>
  </div>
  <p class="v-data">Voting Data</p>
</div>

我正在使用 Font Awesome 库来添加星星。默认情况下,我们希望星星具有黑色描边且无填充。 fa-regular 类为我们做这件事。

我们还希望当用户将鼠标悬停在星星上时,将星星的颜色更改为淡黄色;当用户单击星星时,将星星的颜色更改为橙​​色,以表明他们的评分已被记录。以下 CSS 为我们完成了这一切:

div.rating-wrapper {
  display: flex;
  align-items: first baseline;
  flex-direction: column;
  margin: 5rem;
  font-size: 1.5rem;
}

div.star-wrapper {
  font-size: 2rem;
}

div.star-wrapper i {
  cursor: pointer;
}

div.star-wrapper i.yellow {
  color: #FDD835;
}

div.star-wrapper i.vote-recorded {
  color: #F57C00;
}

p.v-data {
  background: #ccc;
  padding: 0.5rem;
}

编写 jQuery 实现交互

我们现在将使用一些 jQuery 来响应用户事件。我们想要在我们的星星上跟踪两个事件。

让我们从 mouseover 事件开始,这将使我们悬停的恒星及其之前的所有兄弟变成黄色。然而,只有当用户尚未点击星星来登记投票时才会发生这种情况。我们将通过操作 Font Awesome 星形图标的类来实现此目的。

这是我们需要的代码:

$("div.star-wrapper i").on("mouseover", function () {
  if ($(this).siblings("i.vote-recorded").length == 0) {
    $(this).prevAll().addBack().addClass("fa-solid yellow").removeClass("fa-regular");  
    $(this).nextAll().removeClass("fa-solid yellow").addClass("fa-regular");
  }
});

我们使用 if 语句来检查我们当前悬停的明星是否有任何兄弟姐妹,并且附加了 vote-recorded 类。任何此类元素的存在都表明投票已被记录。在这种情况下,我们不进行任何类操作。

但是,如果投票尚未记录,我们将获取当前元素以及该元素之前的所有同级元素,并向其中添加 fa-solidyellow 类。我们还从当前元素后面的所有同级元素中删除这些类。

现在,我们将编写处理 click 事件的 jQuery 代码。每当用户点击第四颗星时,我们就知道他们想给电影评分为四颗星。所以我们记录之前兄弟的数量并加一得到 rating。我们还记录 movie_id 以将评级添加到正确的电影。

$("div.star-wrapper i").on("click", function () {
  let rating = $(this).prevAll().length + 1;
  let movie_id = $(this).closest("div.rating-wrapper").data("id");
  
  if ($(this).siblings("i.vote-recorded").length == 0) {
    
    $(this).prevAll().addBack().addClass("vote-recorded");
    $.post("update_ratings.php", { movie_id: movie_id, user_rating: rating }).done(
      function (data) {
        parent_div.find("p.v-data").text(data);
      }
    );
    
  }
});

我们再次检查是否已为该特定电影记录了投票。如果尚未记录投票,我们将 vote-recorded 类添加到当前单击的元素及其所有先前的同级元素中。

我们还使用 jQuery post() 方法通过 POST 请求将投票数据发送到后端。第一个参数是将处理我们的请求的 PHP 脚本的 URL,而第二个参数是我们要处理的数据。

我们还在 done() 中提供回调,以进一步处理成功处理我们的请求后从服务器发送给我们的数据。

以下 CodePen 演示展示了我们的评级系统的前端外观:

编写PHP记录投票

我们将使用 MySQL 数据库在后端存储我们的投票记录。您可以使用您喜欢的任何应用程序来管理数据库。我正在使用 phpMyAdmin。这里的第一步是创建一个数据库,我将其命名为 rating_test。现在,我们将在数据库中创建一个名为 movie_ ratings 的表。在数据库上运行以下 SQL 查询来创建表:

CREATE TABLE `movie_ratings`(
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `movie_id` VARCHAR(128) NOT NULL DEFAULT '',
    `average_rating` DOUBLE NOT NULL DEFAULT 0,
    `total_votes` DOUBLE NOT NULL DEFAULT 0,
    PRIMARY KEY(`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

执行上述语句将创建一个名为 movie_ ratings 的表,其中包含四个不同的列。

第一个是自动递增的 id,它作为我们添加到表中的每条记录的主键。第二个是 movie_id,它将标识一部电影,最多可以包含 128 个字符。第三个是 average_ rating 来存储迄今为止所有投票的平均值。第四个,total_votes,用于跟踪已投票总数。

再回顾一下上一节中post()方法的第一个参数。您将看到字符串 update_atings.php,这是我们现在需要创建的文件。该文件将包含更新和记录电影评级的 PHP 代码。

$movie_id = $_POST['movie_id'];
$user_rating = $_POST['user_rating'];

$mysqli = new mysqli('localhost', 'root', '', 'rating_test');

if ($mysqli->connect_errno) {
    die("Error while connecting: " . $mysqli->connect_error);
}

我们首先使用 $_POST 获取 POST 数据,然后创建一个新的 mysqli 对象来建立与数据库的连接。然后我们检查 connect_errno 的值,看看我们的数据库连接调用期间是否出现错误。

$rating_query = $mysqli->query("SELECT * from `movie_ratings` WHERE `movie_id` = '$movie_id'");
$rating_query_rows = mysqli_num_rows($rating_query);

if($rating_query_rows == 0) {
    $mysqli->query("INSERT INTO `movie_ratings` (`movie_id`, `average_rating`, `total_votes`) VALUES ('$movie_id', $user_rating, 1)");

    echo "Average Rating: $user_rating Total Votes: 1";
} else {

    $rating_data = $rating_query->fetch_array(MYSQLI_ASSOC);

    $total_votes = $rating_data['total_votes'];
    $average_rating = $rating_data['average_rating'];

    $rating_sum = $average_rating*$total_votes + $user_rating;

    $total_votes += 1;
    $new_average_rating = round($rating_sum/($total_votes), 2);

    $mysqli->query("UPDATE `movie_ratings` SET `average_rating` = $new_average_rating, `total_votes` = $total_votes  WHERE `movie_id` = '$movie_id'");

    echo "Average Rating: $new_average_rating Total Votes: $total_votes";
}

建立连接后,我们运行第一个查询来查看是否已存在要更新其评分的电影的行。

如果没有这样的电影,我们运行另一个查询以将电影插入表中。由于这是该电影的第一次投票,因此我们将总票数设置为 1。

但是,如果表中已经有一行包含我们传递的 movie_id,我们将从该行获取电影的总票数和当前平均评分。之后,我们计算新的评分并相应更新数据库。

最后,我们回显平均评分和总票数的新值以将其显示给用户。

最终想法

为了简单起见,这不是 100% 完整的解决方案。为了扩展这个项目,我们应该存储一个 cookie 以确保人们只投票一次,甚至记录 IP 地址。然而,这是一个很好的开始,并且非常适合跟踪对您网站上的博客文章、评论和图像等项目的投票。

卓越飞翔博客
上一篇: 揭开 Laravel 隐藏的宝藏
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏