javascript - 在 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>
解决方案
追加后重新初始化滑块。
这是如何...
//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>
推荐阅读
- python - 在不迭代项目的情况下获取 dict 键的值
- json - 如何使用jq创建一个没有值的干净json模板文件
- python - Flask Celery TypeError: send_() 为参数“time_”获取了多个值
- laravel - Laravel: Designing a DB table for schedules
- javascript - javascript 过滤/搜索 Html 列表
- python - django 获取切片后无法过滤查询
- extjs - 更改时未检查 RadioButton
- json - How do I programmatically find the path for an asset file I have in Angular?
- flutter - 如何在 Flutter 应用中创建堆叠图像的 GridView?
- linker-errors - ScalaJS:引用不存在的类 play.twirl.api.Html