简体   繁体   中英

Adding new slides in Materialize

I'm using the front-end framework Materialize and the topic is about the slider component Materialize/JS/Media/Slider .

My goal is to add additional slides when you submit the text input that has, for example, "Crime and Punishment", and it will grab the title, description and image from the Google Books API. But the Materialize event listener will ignore the new slide. I think it is ignoring because after I submit the input, I check the HTML elements in the console and all the li tags with the correct class names are added correctly. I think I can refresh the DOM with jQuery but I want to solve this problem in plain 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> 

Re-init the slider after the append.

This is how...

 //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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM