【问题标题】:How to specify API objects in Bootstrap 5 modal?如何在 Bootstrap 5 模式中指定 API 对象?
【发布时间】:2021-10-01 14:33:43
【问题描述】:

我不能直截了当,已经有一段时间了。基本上,我在这个电影应用程序上,需要一个模态。到目前为止,我必须指出要单独放映每部电影,展示它们的海报、标题和配乐。

现在,我们的想法是按下标题,模态框将弹出描述 ${overview}。好的,它有效,但是!模式只显示第一个对象的描述,无论我按哪个电影的标题。

删除模态框并添加 <div>${overview}</div> 后,它可以正常工作,正确显示每部电影的描述,但一旦我将其放入模态框,它将无法正常工作。

我试图通过点击该按钮来玩弄,到处搜索,但找不到解决方案。任何帮助或指导都会很棒,谢谢!

请在此处查看代码:https://github.com/sscip/movie-app-ms2

【问题讨论】:

    标签: javascript modal-dialog bootstrap-modal bootstrap-5


    【解决方案1】:

    是的,你基本上错过了两件事:

    1. 模式内容的文本颜色
    2. 每个按钮和模式的唯一 ID

    这是一个可行的解决方案: P.S:您也可以在 JSfiddle here 上查看。

    // API link with key, please follow readme how to create own API key for application to work.
    
    const APIKey = 'dontreallyneedit';
    const APIURL = "https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=" + APIKey + "&page-1";
    const IMGPath = "https://image.tmdb.org/t/p/w1280";
    const SearchAPI = "https://api.themoviedb.org/3/search/movie?&api_key=" + APIKey + "&query=";
    
    const mainSection = document.getElementById("main-section"); // selecting DOM element to work with
    const searchForm = document.getElementById("search-form");
    const searchInput = document.getElementById("search-field");
    
    
    movies(APIURL); // calling popular movies funcion to work 
    
    async function movies(url) {
      /* const resp = await fetch(url);
      const respData = await resp.json(); */
    
      const results = [{
          poster_path: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTP4mb3V7kJHqWTf5GUr-wHUOfHaTv71Ypf3-WGYqjJr-OpYPJslwk2IYY-Phi4hGxpfFQ&usqp=CAU",
          title: "Movie 1",
          vote_average: 5,
          overview: "Great Overview One!"
        },
        {
          poster_path: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTP4mb3V7kJHqWTf5GUr-wHUOfHaTv71Ypf3-WGYqjJr-OpYPJslwk2IYY-Phi4hGxpfFQ&usqp=CAU",
          title: "Movie 2",
          vote_average: 4,
          overview: "Great Overview Two!"
        },
        {
          poster_path: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTP4mb3V7kJHqWTf5GUr-wHUOfHaTv71Ypf3-WGYqjJr-OpYPJslwk2IYY-Phi4hGxpfFQ&usqp=CAU",
          title: "Movie 3",
          vote_average: 3,
          overview: "Great Overview Three!"
        }
    
      ];
    
      showMovies(results);
    }
    
    function showMovies(movies) {
    
    
      mainSection.innerHTML = ""; // clearing page to show new reults
    
      movies.forEach((movie, index) => {
        const {
          poster_path,
          title,
          vote_average,
          overview
        } = movie; // Pulling necessary names from API
    
        const movieBox = document.createElement("div"); //creating a div for individual movie elements
        movieBox.classList.add("movie"); // creating a class for it
    
        movieBox.innerHTML = `
          <div class="movie-image"><img src="${poster_path}" alt="${title}" /></div>
          <div class="movie-info">
            <button type="button" class="btn" data-bs-toggle="modal" data-bs-target="#exampleModal_${index}">
              ${title}
            </button>
            <span class="${classByRating(vote_average)}">${vote_average}</span>
            
            <div class="modal fade" id="exampleModal_${index}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
              <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
                <div class="modal-content">
                  <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">${title}</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                  </div>
                  <div class="modal-body">
                    ${overview}
                  </div>
                  <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        `; // creating markup for every movie element and pulling information from API
        mainSection.appendChild(movieBox); // sending back to HTML file
      });
    }
    
    
    function classByRating(vote) { //checking how high is the movie rating and giving apropriate class name.
      if (vote >= 8) {
        return "green";
      } else if (vote >= 5) {
        return "amber"
      } else {
        return "red";
      }
    }
    
    
    searchForm.addEventListener("submit", (i) => {
      i.preventDefault();
    
      const searchTerm = searchInput.value;
    
      if (searchTerm) {
        movies(SearchAPI + searchTerm)
        searchInput.value = "";
      }
    })
    @import url('https://fonts.googleapis.com/css2?family=Lato:wght@100;300&display=swap');
    .modal-content {
      color: black;
    }
    
    
    /* Main Styles */
    
    * {
      box-sizing: border-box;
      font-family: 'Lato', serif;
    }
    
    
    /* Navigation */
    
    header {
      background-color: #D16BA5;
      padding: 1rem 0.5rem;
    }
    
    header a {
      font-size: 1.5rem;
    }
    
    header button:focus {
      outline: none;
    }
    
    #navbar-brand {
      font-size: 1.7rem;
    }
    
    #search-field {
      border-radius: 10px;
      font-size: 1.2rem;
      border: none;
    }
    
    .search-btn:focus {
      outline: none;
    }
    
    .search-btn:active {
      background-color: #FF8F80;
    }
    
    .search-btn {
      font-size: 1.2rem;
      padding: 0 1rem;
      border: none;
      border-radius: 10px;
      color: #eee;
      background-color: #FF8F80;
    }
    
    
    /* Main section styling */
    
    #main-section {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
    }
    
    
    /* Movies Box styling */
    
    .movie {
      margin: 0.7rem;
      width: 15rem;
      border-radius: 5px;
      background-color: #FF8F80;
      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
      overflow: hidden;
    }
    
    
    /* Movie image */
    
    .movie img {
      max-width: 100%;
    }
    
    
    /* Movie Basic info */
    
    .movie-info {
      display: flex;
      justify-content: space-between;
      color: #eee;
      padding: 0.5rem;
      align-items: center;
      max-height: 100%;
    }
    
    .movie-info h3 {
      margin: 0;
      font-size: 1.21rem;
    }
    
    .movie-info span {
      background-color: #D16BA5;
      padding: 0.5rem;
      border-radius: 5px;
      width: 2.5rem;
      height: 2.5rem;
      text-align: center;
      font-weight: bold;
    }
    
    .movie-info span.green {
      color: rgb(0, 214, 54);
    }
    
    .movie-info span.amber {
      color: rgb(255, 163, 87);
    }
    
    .movie-info span.red {
      color: rgb(223, 45, 0);
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!-- Title -->
      <title>Movies TOP-20 LIVE!</title>
      <!-- Bootstrap 5 CSS -->
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
      <!-- Font Awesome 5 -->
      <script src="https://kit.fontawesome.com/0d4c39c5bf.js" crossorigin="anonymous"></script>
      <!-- Custom CSS -->
      <link rel="stylesheet" href="assets/css/styles.css" />
      <!-- Custom JS -->
      <script src="assets/js/config.js" type="text/javascript" defer></script>
      <script src="assets/js/script.js" type="text/javascript" defer></script>
    </head>
    
    <body>
      <header>
        <nav class="navbar navbar-expand-lg navbar-dark">
          <div class="container-fluid">
            <a class="navbar-brand" id="navbar-brand" href="#">Movies TOP-20 LIVE</a>
            <button class="navbar-toggler" id="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
              <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarSupportedContent">
              <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                  <a class="nav-link active" aria-current="page" href="#">Home</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" href="#">Contact Us</a>
                </li>
              </ul>
              <form class="d-flex" id="search-form">
                <input class="form-control me-2" id="search-field" type="search" placeholder="Search" aria-label="Search">
                <button class="search-btn" id="search-btn" type="submit">
                  Search
                </button>
              </form>
            </div>
          </div>
        </nav>
      </header>
      <section id="main-section"></section>
    
      <!-- Bootstrap 5 JS -->
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    </body>
    
    </html>

    【讨论】:

    • 是的!!!!谢谢!我没有使用 ${index},但在 API 中找到了一个 ${id}。所以它现在可以工作了!谢谢!!!!!!!!样式不是现阶段的重点,我希望功能发挥作用!现在它起作用了!谢谢!现在将破解样式)
    【解决方案2】:

    您需要更改data-bs-target 来绑定不同的按钮和模式。

      movies.forEach((movie) => {
        const {poster_path, title, vote_average, overview, uid} = movie; // Pulling necessary names from API
        console.log(overview)
    
        const movieBox = document.createElement("div"); //creating a div for individual movie elements
        movieBox.classList.add("movie"); // creating a class for it
    
        movieBox.innerHTML = `
          <div class="movie-image"><img src="${IMGPath + poster_path}" alt="${title}" /></div>
          <div class="movie-info">
            <button type="button" class="btn" data-bs-toggle="modal" data-bs-target="#${uid}">
              ${title}
            </button>
            <span class="${classByRating(vote_average)}">${vote_average}</span>
            
            <div class="modal fade" id="${uid}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
              <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
                <div class="modal-content">
                  <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">${title}</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                  </div>
                  <div class="modal-body">
                    ${overview}
                  </div>
                  <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        `; // creating markup for every movie element and pulling information from API
    
        
    
        mainSection.appendChild(movieBox); // sending back to HTML file
      });
    

    varying-modal-content

    【讨论】:

    • 是的,这两个例子都是正确的。我用 ${id} 而不是 ${uid},花了我一段时间才明白)谢谢!
    猜你喜欢
    • 2021-10-05
    • 2022-11-02
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-21
    • 2023-04-06
    相关资源
    最近更新 更多