【问题标题】:What is the best way to eliminate repetitive code消除重复代码的最佳方法是什么
【发布时间】:2020-09-30 13:13:06
【问题描述】:

我写信是想问如何摆脱我正在构建的页面的重复代码。我大约一个月前开始学习html。我知道其他语言,但除了 C 之外从未使用过任何其他语言。我对 C 的了解来自大约 10 年前我参加的两门编程大学入门课程。在这 10 年的差距中,我做了零编程。

我的页面当前有一个容器、一个行和三个列。每个列都包含一个引导卡。我希望最终在多页上有几十或几百行卡片。如果我尝试添加更多行卡片,我很快就会得到数百行重复代码。如果我想在未来对卡片进行更改,我想这会带来很大的问题。

据我所知,每张卡片唯一独特的组成部分是 href 和 img src 链接、卡片标题和卡片文本。

我一直在阅读有关如何消除重复代码的信息。我遇到了几篇文章,我发现我无法单独使用 html 来实现这一点。提到的文章使用了我不熟悉的其他语言和方法,如 javascript、jquery、模板引擎、blockwrapper。我想有几种方法可以摆脱重复。我的想法是使用对象或函数将唯一信息传递到卡片中,但我不知道该怎么做。

我想使用一种简单、传统的方法,并且可以向我介绍新的技能/语言。我也对新颖或非常规的方法持开放态度。非常感谢您的帮助。

Screenshot of the page .

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="styles.css">
    <title>Index Page</title>
</head>
<body>
    
    <div class="container">
    <div class="row">

      <div class="col">
        <div class="card text-center border-0 d-flex align-items-center justify-content-center">
          <a href="https://www.youtube.com/watch?v=iEGFFyv0MH4&t=1070s">
            <img src="https://i.ytimg.com/an_webp/iEGFFyv0MH4/mqdefault_6s_480x270.webp?du=3000&sqp=CLj_hPcF&rs=AOn4CLDOvo2tUWkm3QGC8E1BjBEWRa55Hw" style="width:80px;height:80px;">
          </a>
          <div class="card-body">
            <h5 class="card-title">Video 1</h5>
            <p class="card-text">Nighttime Ramen ???? [jazzy beats / lofi hip hop mix]</p>
            <a href="https://www.youtube.com/watch?v=iEGFFyv0MH4&t=1070s" class="btn btn-primary">View Video</a>
          </div>
        </div>
      </div>

      <div class="col">
        <div class="card text-center border-0 d-flex align-items-center justify-content-center">
          <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0">
            <img src="https://i.ytimg.com/an_webp/8Zuwg_1Uit0/mqdefault_6s.webp?du=3000&sqp=CKixhfcF&rs=AOn4CLD445U_D61yZfcEysryoe_REtuCog" style="width:80px;height:80px;">
          </a>
          <div class="card-body">
            <h5 class="card-title">Video 2</h5>
            <p class="card-text">National anthem of Vietnam shown on VTV1 each morning</p>
            <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0" class="btn btn-primary">View Video</a>
          </div>
        </div>
      </div>

      <div class="col">
        <div class="card text-center border-0 d-flex align-items-center justify-content-center">
          <a href="https://www.youtube.com/watch?v=_rTuPEdlhQs">
            <img src="https://i.ytimg.com/an_webp/_rTuPEdlhQs/mqdefault_6s.webp?du=3000&sqp=CI64hfcF&rs=AOn4CLBuV_ZCwrAUoIj_dfv3in_OlYytNQ" style="width:80px;height:80px;">
          </a>
          <div class="card-body">
            <h5 class="card-title">Video 3</h5>
            <p class="card-text">Baby Boomers Speaking To Us From 1989</p>
            <a href="https://www.youtube.com/watch?v=_rTuPEdlhQs" class="btn btn-primary">View Video</a>
          </div>
        </div>
      </div>

    </div>
    </div>
</body>
</html>

【问题讨论】:

  • 对于您所描述的情况,我真的建议您使用数据库存储视频网址。您甚至可以创建一个简单的管理页面,其中只有一个输入字段和一个添加按钮,以将未来的 url 存储在您的数据库中 - 如果您不想手动通过数据库工作台执行此操作。无论如何,这个想法是您从数据库中获取 url,使用从数据库中获取的 url 循环一个 html 标记结构。然后,您的标记将根据数据库中视频网址的数量动态创建。如果你愿意,我可以给你一个 PHP 的小例子。
  • 我对您从数据库中获取 url 并为 html 标记结构使用循环的想法非常感兴趣。非常感谢您提供的那个小例子!
  • 您是否找到了将继续推进的解决方案?
  • 感谢您的帮助,马丁。我想继续你的解决方案。我很好奇,在这种情况下,是否有替代数据库来存储 url?是否可以使用数组或 txt 文件之类的东西来存储适当的值?然后就像在您的示例中一样,从该数组或文件中获取数据以用于围绕 HTML 结构的周围循环?
  • 是的,您可以将值存储到数组中。甚至是一个文件(比如说 CSV 文件)并将该内容存储到一个数组中。您可以使其多维来表示数据库示例中相同数量的字段。您还可以对数组进行硬编码,并在进行过程中简单地添加新元素。方法相同,循环遍历数组并打印[i] 索引以获取内容。

标签: javascript html function object


【解决方案1】:

就像我在评论中提到的那样,我建议您使用数据库存储适当的值,然后从数据库中获取数据并围绕视频的 HTML 结构创建一个环绕循环。

这样,您将根据存储在数据库中的视频数量动态创建内容。

首先我们需要建立数据库并拥有一些示例数据。 MySQL 示例:

-- phpMyAdmin SQL Dump
-- version 4.9.2
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3306
-- Generation Time: Jun 11, 2020 at 02:07 AM
-- Server version: 10.4.10-MariaDB
-- PHP Version: 7.3.12

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `videodb`
--

-- --------------------------------------------------------

--
-- Table structure for table `videos`
--

DROP TABLE IF EXISTS `videos`;
CREATE TABLE IF NOT EXISTS `videos` (
  `video_id` int(11) NOT NULL AUTO_INCREMENT,
  `video_url` varchar(2500) NOT NULL,
  `thumbnail_url` varchar(2500) NOT NULL,
  `video_description` varchar(500) NOT NULL,
  PRIMARY KEY (`video_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

--
-- Dumping data for table `videos`
--

INSERT INTO `videos` (`video_id`, `video_url`, `thumbnail_url`, `video_description`) VALUES
(1, 'https://www.youtube.com/watch?v=iEGFFyv0MH4&t=1070s', 'https://i.ytimg.com/an_webp/iEGFFyv0MH4/mqdefault_6s_480x270.webp?du=3000&sqp=CLj_hPcF&rs=AOn4CLDOvo2tUWkm3QGC8E1BjBEWRa55Hw', 'description of video 1'),
(2, 'https://www.youtube.com/watch?v=8Zuwg_1Uit0', 'https://i.ytimg.com/an_webp/8Zuwg_1Uit0/mqdefault_6s.webp?du=3000&sqp=CKixhfcF&rs=AOn4CLD445U_D61yZfcEysryoe_REtuCog', 'Description of video 2'),
(3, 'https://www.youtube.com/watch?v=_rTuPEdlhQs', 'https://i.ytimg.com/an_webp/_rTuPEdlhQs/mqdefault_6s.webp?du=3000&sqp=CI64hfcF&rs=AOn4CLBuV_ZCwrAUoIj_dfv3in_OlYytNQ', 'Description of video 3');
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

将其复制粘贴到 MySQL 工作台中应该会创建具有我为提供此示例而使用过的所有相同属性的数据库。

至于网站示例,我将使用 PHP 作为我的后端脚本语言并使用 mysqli 面向对象的语法。

如果您继续采用这种编程风格,需要提及的重要一点是,如果您以后要处理用户输入,请记住使用参数化、准备好的语句。这非常重要。否则,您将面临 SQL 注入(SQLI 攻击)。

网站示例:

<?php
// DB variables
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "videodb";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if($conn->connect_error){
  die("Connection failed: " . $conn->connect_error);
}

// Declare the query
$sql = "SELECT video_id, video_url, thumbnail_url, video_description FROM videos";

// Prepare
$stmt = $conn->prepare($sql);

// Execute the query
$stmt->execute();

// Get result of query
$result = $stmt->get_result();

// Close connection
$stmt->close();
$conn->close();
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
        <link rel="stylesheet" href="styles.css">
        <title>Index Page</title>
    </head>
    <body>
        <div class="container">
            <div class="row">
                <?php
                // Check if any rows are returned
                if($result->num_rows > 0) {
                    // Loop through the result(s)
                    while ($data = $result->fetch_assoc())
                    {
                        ?>
                        <div class="col-md-4">
                            <div class="card text-center border-0 d-flex align-items-center justify-content-center">
                                <a href="<?php echo $data['video_url']; ?>">
                                    <img src="<?php echo $data['thumbnail_url']; ?>" style="width:250px;height:250px;" />
                                </a>
                                <div class="card-body">
                                    <h5 class="card-title">Video <?php echo $data['video_id']; ?></h5>
                                     <p class="card-text"><?php echo $data['video_description']; ?></p>
                                     <a href="<?php echo $data['video_url']; ?>" class="btn btn-primary">View Video</a>
                                </div>
                            </div>
                        </div>
                        <?php
                     }
                }
                // If no rows, no videos were found
                else
                {
                    ?><div class="col text-center"><h1>NO VIDEOS FOUND</h1></div><?php
                }
                ?>
            </div>
        </div>
    </body>
</html>

就像我在评论中提到的那样,您甚至可以创建一个小型管理页面,您可以在其中包含用于视频和缩略图 URL 的 &lt;input type="text" /&gt; 元素、用于视频描述的 &lt;textarea&gt; 元素和用于将所有值添加到数据库中,这样您就不必通过数据库工作台来完成。

编辑:

您在评论中询问在存储视频数据方面是否有数据库方法的替代方案。

您可以做的一件事是利用多维数组并循环遍历它。这基本上也是您从数据库中获取数据时所做的事情。

示例:

<?php
// multi-dimensional array
$videoArray = array(
                array(
                    "1", 
                    "https://www.youtube.com/watch?v=iEGFFyv0MH4&t=1070s",
                    "https://i.ytimg.com/an_webp/iEGFFyv0MH4/mqdefault_6s_480x270.webp?du=3000&sqp=CLj_hPcF&rs=AOn4CLDOvo2tUWkm3QGC8E1BjBEWRa55Hw",
                    "Description of video 1"
                ),
                array(
                    "2", 
                    "https://www.youtube.com/watch?v=8Zuwg_1Uit0",
                    "https://i.ytimg.com/an_webp/8Zuwg_1Uit0/mqdefault_6s.webp?du=3000&sqp=CKixhfcF&rs=AOn4CLD445U_D61yZfcEysryoe_REtuCog",
                    "Description of video 2"
                ),
                array(
                    "3", 
                    "https://www.youtube.com/watch?v=iEGFFyv0MH4&t=1070s",
                    "https://i.ytimg.com/an_webp/_rTuPEdlhQs/mqdefault_6s.webp?du=3000&sqp=CI64hfcF&rs=AOn4CLBuV_ZCwrAUoIj_dfv3in_OlYytNQ",
                    "Description of video 3"
                )
            );

$video_id = 0; // id index
$video_url = 1; // video url index
$video_thumbnail = 2; // thumbnail url index
$video_description = 3; // description index

// check if any data
if(count($videoArray) > 0)
{
    // loop through array
    for($i = 0; $i < count($videoArray); $i++)
    {
        ?>
        <div class="col-md-4">
            <div class="card text-center border-0 d-flex align-items-center justify-content-center">
                <a href="<?php echo $videoArray[$i][$video_url]; ?>">
                    <img src="<?php echo $videoArray[$i][$video_thumbnail]; ?>" style="width:250px;height:250px;" />
                </a>
                <div class="card-body">
                    <h5 class="card-title">Video <?php echo $videoArray[$i][$video_id]; ?></h5>
                     <p class="card-text"><?php echo $videoArray[$i][$video_description]; ?></p>
                     <a href="<?php echo $videoArray[$i][$video_url]; ?>" class="btn btn-primary">View Video</a>
                </div>
            </div>
        </div>
        <?php
    }
}
// else if no data, no videos were found
else
{
     ?><div class="col text-center"><h1>NO VIDEOS FOUND</h1></div><?php
}
?>

您还可以拥有一个包含视频数据的文件。假设一个.CSV 文件,然后您可以使用delimiter 来分隔您的内容,将该文件中的数据存储到一个多维数组中,并以相同的方法使用它。

当您保存 CSV 文件(至少从 Excel 中)时,您可以选择所需的分隔类型。在您的情况下,; 将是 delimiter 的绝佳选择。

我不会详细介绍如何加载 CSV 文件并根据其内容构建数组。如果你想研究它,你可以自己研究它。我觉得这本身就是另一个问题,最好与这个问题分开提出。

【讨论】:

    【解决方案2】:

    那是不可能的。 HTML 是一种标记语言,不能用于定义逻辑,例如生成内容的方法。

    【讨论】:

    • 好吧,JavaScript 总是存在的。
    【解决方案3】:

    由于 HTML 是浏览器处理的最终结果,如果不使用 Javascript(或任何 JS 框架,如 jQuery、Angular、React...),您几乎无能为力

    您唯一能做的就是减少 HTML 的占用空间,但如果您使用引导程序(您被绑定到它的标记以允许使用它的样式),这将变得不可能。

    例如,您的视频块可以是这样的:

    .video-card-container {
      display: flex;
    }
    
    .video-card {
      text-align: center;
      font-family: sans-serif;
    }
    
    .video-card > div > h5 {
      font-size: 18px;
    }
    
    .video-card > div > p {
      font-size: 14px;
    }
    
    .video-card > div > a {
      border-radius: 4px;
      background-color: #6666FF;
      color: white;
      padding: 8px 10px;
      text-decoration: none;
    }
    <div class="video-card-container">
        <div class="video-card">
          <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0">
            <img src="https://i.ytimg.com/an_webp/8Zuwg_1Uit0/mqdefault_6s.webp?du=3000&sqp=CKixhfcF&rs=AOn4CLD445U_D61yZfcEysryoe_REtuCog" style="width:80px;height:80px;">
          </a>
          <div>
            <h5>Video 2</h5>
            <p>National anthem of Vietnam shown on VTV1 each morning</p>
            <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0">View Video</a>
          </div>
        </div>
        <div class="video-card">
          <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0">
            <img src="https://i.ytimg.com/an_webp/8Zuwg_1Uit0/mqdefault_6s.webp?du=3000&sqp=CKixhfcF&rs=AOn4CLD445U_D61yZfcEysryoe_REtuCog" style="width:80px;height:80px;">
          </a>
          <div>
            <h5>Video 2</h5>
            <p>National anthem of Vietnam shown on VTV1 each morning</p>
            <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0">View Video</a>
          </div>
        </div>
        <div class="video-card">
          <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0">
            <img src="https://i.ytimg.com/an_webp/8Zuwg_1Uit0/mqdefault_6s.webp?du=3000&sqp=CKixhfcF&rs=AOn4CLD445U_D61yZfcEysryoe_REtuCog" style="width:80px;height:80px;">
          </a>
          <div>
            <h5>Video 2</h5>
            <p>National anthem of Vietnam shown on VTV1 each morning</p>
            <a href="https://www.youtube.com/watch?v=8Zuwg_1Uit0">View Video</a>
          </div>
        </div>
    </div>

    由于 video-card 的标记始终是 this,样式表 (css) 变得非常简单,您不需要为所有内容放置很多类。

    缺点是您将无法利用引导程序。

    【讨论】:

    • 谢谢你的例子。你提到几乎没有办法只用 html 来做到这一点。请问您如何使用Javascript来实现这一点?
    • JavaScript 只会减少手动创建的标记,但最终还是会得到很多标记
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    相关资源
    最近更新 更多