首页 > 解决方案 > 在 Materialise 中添加新幻灯片

问题描述

我正在使用前端框架 Materialize,主题是关于滑块组件Materialize/JS/Media/Slider的。

我的目标是在您提交具有例如“犯罪与惩罚”的文本输入时添加额外的幻灯片,它将从 Google Books API 中获取标题、描述和图像。但 Materialize 事件侦听器将忽略新幻灯片。我认为它被忽略了,因为在我提交输入后,我检查了控制台中的 HTML 元素,并且所有具有正确类名的 li 标签都被正确添加。我想我可以用 jQuery 刷新 DOM,但我想用纯 JavaScript 解决这个问题。

//Materialize JS
document.addEventListener('DOMContentLoaded', function() {
  let elems = document.querySelectorAll('.slider');
  let instances = M.Slider.init(elems, {
    height: 300,
    interval: 1000,
  });
});


//Dynamic Slide
bookList = document.querySelector('.book-list');


document.querySelector('button').addEventListener('click', getBook);

function getBook(e) {
  const book = document.querySelector('input[type="text"]').value;

  const xhr = new XMLHttpRequest();

  xhr.open('GET' ,`https://www.googleapis.com/books/v1/volumes?q=${book}`, true);

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

      let output = '';

      const li = document.createElement('li');
      
      const liBullet = document.createElement('li');
      liBullet.className = 'indicator-item';

      if(response.kind === 'books#volumes'){

        for(let i = 0; i < response.items.length; i++){
          if(response.items[i].volumeInfo.imageLinks){
            output = `
                  <img src="${response.items[i].volumeInfo.imageLinks.thumbnail}">
                  <div class="caption center-align">
                    <h3>${response.items[0].volumeInfo.title}</h3>
                    <h4>${response.items[0].volumeInfo.authors[0]}</h4>
                    <h6>${response.items[0].volumeInfo.description}</h6>
                  </div>`;
          }
        }
          

      } else {
        output += '<li>Something went wrong :S</li>';
      }
      
      li.innerHTML = output;
      bookList.appendChild(li);
      bookList.nextElementSibling.appendChild(liBullet);         
    }
  }          

  xhr.send();

  e.preventDefault();
}
<!DOCTYPE html>
  <html>
    <head>
      <!--Import Google Icon Font-->
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
      <!--Import materialize.css-->
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">

      <!--Let browser know website is optimized for mobile-->
      <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
      <title>Book List</title>
    </head>

    <body>
      <nav class="green accent-3">
        <div class="nav-wrapper">
          <a href="#" class="brand-logo">Logo</a>
          <ul id="nav-mobile" class="right hide-on-med-and-down">
            <li><a href="sass.html">Sass</a></li>
            <li><a href="badges.html">Components</a></li>
            <li><a href="collapsible.html">JavaScript</a></li>
          </ul>
        </div>
      </nav>
      <div class="slider">
        <ul class="slides book-list">
          <li>
            <!-- random image -->
            <div class="caption center-align">
              <h3>This is our big Tagline!</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
          <li>
            <div class="caption left-align">
              <h3>Left Aligned Caption</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
          <li>
            <div class="caption right-align">
              <h3>Right Aligned Caption</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
          <li>
            <div class="caption center-align">
              <h3>This is our big Tagline!</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
        </ul>
      </div>
      <div class="row ">
        <div class="col s12">
          <div class="row">
            <div class="input-field col l11 m10 s9">
              <i class="material-icons prefix ">search</i>
              <input type="text" id="autocomplete-input" class="autocomplete ">
              <label for="autocomplete-input" class="change">Autocomplete</label>
            </div>
            <div class="col l1 m2 s3">
              <button class="btn waves-effect waves-green" type="submit" name="action">Submit
              </button>
            </div>
          </div>
        </div>
      </div>

      <!--JavaScript at end of body for optimized loading-->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
      <script src="app.js"></script>
    </body>
  </html>

标签: javascriptslidermaterialize

解决方案


追加后重新初始化滑块。

这是如何...

//Materialize JS
document.addEventListener('DOMContentLoaded', function() {
  let elems = document.querySelectorAll('.slider');
  let instances = M.Slider.init(elems, {
    height: 300,
    interval: 1000,
  });
});


//Dynamic Slide
bookList = document.querySelector('.book-list');


document.querySelector('button').addEventListener('click', getBook);

function getBook(e) {
  const book = document.querySelector('input[type="text"]').value;

  const xhr = new XMLHttpRequest();

  xhr.open('GET' ,`https://www.googleapis.com/books/v1/volumes?q=${book}`, true);

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

      let output = '';

      const li = document.createElement('li');
      
      const liBullet = document.createElement('li');
      liBullet.className = 'indicator-item';

      if(response.kind === 'books#volumes'){

        for(let i = 0; i < response.items.length; i++){
          if(response.items[i].volumeInfo.imageLinks){
            output = `
                  <img src="${response.items[i].volumeInfo.imageLinks.thumbnail}">
                  <div class="caption center-align">
                    <h3>${response.items[0].volumeInfo.title}</h3>
                    <h4>${response.items[0].volumeInfo.authors[0]}</h4>
                    <h6>${response.items[0].volumeInfo.description}</h6>
                  </div>`;
          }
        }
          

      } else {
        output += '<li>Something went wrong :S</li>';
      }
      
      li.innerHTML = output;
      bookList.appendChild(li);
      bookList.nextElementSibling.appendChild(liBullet);  
        let elems = document.querySelectorAll('.slider');
  let instances = M.Slider.init(elems, {
    height: 300,
    interval: 1000,
  });
    }
  }          

  xhr.send();

  e.preventDefault();
}
<!DOCTYPE html>
  <html>
    <head>
      <!--Import Google Icon Font-->
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
      <!--Import materialize.css-->
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">

      <!--Let browser know website is optimized for mobile-->
      <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
      <title>Book List</title>
    </head>

    <body>
      <nav class="green accent-3">
        <div class="nav-wrapper">
          <a href="#" class="brand-logo">Logo</a>
          <ul id="nav-mobile" class="right hide-on-med-and-down">
            <li><a href="sass.html">Sass</a></li>
            <li><a href="badges.html">Components</a></li>
            <li><a href="collapsible.html">JavaScript</a></li>
          </ul>
        </div>
      </nav>
      <div class="slider">
        <ul class="slides book-list">
          <li>
            <!-- random image -->
            <div class="caption center-align">
              <h3>This is our big Tagline!</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
          <li>
            <div class="caption left-align">
              <h3>Left Aligned Caption</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
          <li>
            <div class="caption right-align">
              <h3>Right Aligned Caption</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
          <li>
            <div class="caption center-align">
              <h3>This is our big Tagline!</h3>
              <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
            </div>
          </li>
        </ul>
      </div>
      <div class="row ">
        <div class="col s12">
          <div class="row">
            <div class="input-field col l11 m10 s9">
              <i class="material-icons prefix ">search</i>
              <input type="text" id="autocomplete-input" class="autocomplete ">
              <label for="autocomplete-input" class="change">Autocomplete</label>
            </div>
            <div class="col l1 m2 s3">
              <button class="btn waves-effect waves-green" type="submit" name="action">Submit
              </button>
            </div>
          </div>
        </div>
      </div>

      <!--JavaScript at end of body for optimized loading-->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
      <script src="app.js"></script>
    </body>
  </html>


推荐阅读