API 调用后 Slick JS 幻灯片不工作
SlickJS slides not working after API call
我对 slickjs
有疑问。我的应用正在从天气 API 获取数据。我想将这些数据放入 sildes 中。 Sildes 由 forEach
和模板字符串创建。问题是 slickjs 需要将它的容器应用于我插入幻灯片的父元素,这没关系。但是,如果幻灯片是在某些事件之后创建的,在我的情况下,用户 slickjs 获取数据看不到我的幻灯片,并且不会对它们应用 class 以使其工作。但是,如果我重新调整页面大小,以便浏览器解析 JS 并应用那些 classes,那么滑块就可以工作了。
app.js
import { fetchForcast } from './fetch'
import { ui } from './ui'
let btn = document.getElementById('btn')
btn.addEventListener('click', getWeather)
function getWeather() {
let city = document.getElementById('city').value
let country = document.getElementById('country').value
fetchForcast.fetchCall(country, city)
.then(res => ui.showWeather(res.resData))
.catch(err => console.log(err));
fetchForcast.fetchCurrent(country, city)
.then(res => ui.showCurrent(res.resData))
.catch(err => console.log(err));
}
$(window).on('load', function() {
window.slickSettings = {
autoplay: false,
autoplaySpeed: 4000,
slidesToShow: 3,
slidesToScroll: 3,
dots: false,
arrows: false,
responsive: [{
breakpoint: 990,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
}, {
breakpoint: 550,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
};
$('.forcast').slick(window.slickSettings);
})
UI class
class UI {
showCurrent(weather) {
let rain = weather.weather[0].main
if (rain === "Rain") {
document.body.style.background = "url('https://images.pexels.com/photos/459451/pexels-photo-459451.jpeg?cs=srgb&dl=black-and-white-clear-cool-459451.jpg&fm=jpg')";
}
let output = ''
output += `
<div class="current__weather-box">
<h5 class="city">${weather.name}</h5>
<span class="country">${weather.sys.country}</span>
<span class="desc">${weather.weather[0].description}</span>
<ul>
<li><span>humidity:</span><span>${weather.main.humidity}%</span></li>
<li><span>temperature:</span><span>${weather.main.pressure}</span></li>
<li><span>temperature:</span><span>${weather.main.temp}</span></li>
<li><span>max:</span><span></span>${weather.main.temp_max}</li>
<li><span>min:</span><span></span>${weather.main.temp_min}</li>
</ul>
</div>
`
document.getElementById('current-weather').innerHTML = output
}
showWeather(weather) {
let output = ''
let forcasts = weather.list.slice(1, 5)
forcasts.forEach(forcast => {
output += `
<div class="forcast__box">
<span>${forcast.dt_txt}</span>
<ul>
<li>${forcast.weather[0].description}</li>
<li>${forcast.main.humidity}</li>
<li>${forcast.main.pressure}</li>
<li>${forcast.main.temp}</li>
<li>${forcast.main.humidity}</li>
</ul>
</div> `
})
document.getElementById('forcast').innerHTML = output;
$('.forcast').slick('resize');
}
}
export const ui = new UI()
slickjs
$(document).ready(function() {
$('.forcast').slick({
autoplay: false,
autoplaySpeed: 4000,
slidesToShow: 3,
slidesToScroll: 3,
dots: false,
arrows: false,
responsive: [{
breakpoint: 990,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
}, {
breakpoint: 550,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
});
})
将您的 slickSettings 保存在一个全局变量中(实际上是在一个随处可用的变量中,您需要初始化一个 slick 实例):
$(window).on('load', function() {
window.slickSettings = {
autoplay: false,
... // <= rest of your slick settings
};
$('.forcast').slick(window.slickSettings);
})
...并且,在您的 ajax 调用中,使用相同的设置重新初始化 slick:
... { ...
document.getElementById('forcast').innerHTML = output;
$('.forcast').slick(window.slickSettings); // <= add this line
...
}
注意:你不需要真的需要污染window
对象 属性 并且您的设置很可能只存在于一个单独的变量中,但是,由于我对您的系统一无所知,所以上面的设置肯定会起作用。通常,您希望避免向 window 对象添加属性,并尝试将变量的范围限制在完成工作所需的范围内。
另一种选择是在更新 html 后在 window
上触发 resize
事件。不在 .forcast
上! resize
事件不会冒泡,只能放在 window
对象上:
Only handlers registered on the window object will receive events.
仔细查看示例页面,您有 slickAdd
方法:
$('.forcast').slick('slickAdd',output);
...但要实现此功能 output
只需要额外的幻灯片。
这似乎也有效:
$('.forcast')[0].slick.refresh();
您可以在将标记插入 DOM 以强制 slick 重新初始化后手动触发调整大小事件
$('.forcast').slick('resize');
或者等待 slick.js 初始化,直到 DOM 创建完成。
现在你在 $(document).ready()
上初始化 slick,它在 ajax 调用完成之前被调用。
我对 slickjs
有疑问。我的应用正在从天气 API 获取数据。我想将这些数据放入 sildes 中。 Sildes 由 forEach
和模板字符串创建。问题是 slickjs 需要将它的容器应用于我插入幻灯片的父元素,这没关系。但是,如果幻灯片是在某些事件之后创建的,在我的情况下,用户 slickjs 获取数据看不到我的幻灯片,并且不会对它们应用 class 以使其工作。但是,如果我重新调整页面大小,以便浏览器解析 JS 并应用那些 classes,那么滑块就可以工作了。
app.js
import { fetchForcast } from './fetch'
import { ui } from './ui'
let btn = document.getElementById('btn')
btn.addEventListener('click', getWeather)
function getWeather() {
let city = document.getElementById('city').value
let country = document.getElementById('country').value
fetchForcast.fetchCall(country, city)
.then(res => ui.showWeather(res.resData))
.catch(err => console.log(err));
fetchForcast.fetchCurrent(country, city)
.then(res => ui.showCurrent(res.resData))
.catch(err => console.log(err));
}
$(window).on('load', function() {
window.slickSettings = {
autoplay: false,
autoplaySpeed: 4000,
slidesToShow: 3,
slidesToScroll: 3,
dots: false,
arrows: false,
responsive: [{
breakpoint: 990,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
}, {
breakpoint: 550,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
};
$('.forcast').slick(window.slickSettings);
})
UI class
class UI {
showCurrent(weather) {
let rain = weather.weather[0].main
if (rain === "Rain") {
document.body.style.background = "url('https://images.pexels.com/photos/459451/pexels-photo-459451.jpeg?cs=srgb&dl=black-and-white-clear-cool-459451.jpg&fm=jpg')";
}
let output = ''
output += `
<div class="current__weather-box">
<h5 class="city">${weather.name}</h5>
<span class="country">${weather.sys.country}</span>
<span class="desc">${weather.weather[0].description}</span>
<ul>
<li><span>humidity:</span><span>${weather.main.humidity}%</span></li>
<li><span>temperature:</span><span>${weather.main.pressure}</span></li>
<li><span>temperature:</span><span>${weather.main.temp}</span></li>
<li><span>max:</span><span></span>${weather.main.temp_max}</li>
<li><span>min:</span><span></span>${weather.main.temp_min}</li>
</ul>
</div>
`
document.getElementById('current-weather').innerHTML = output
}
showWeather(weather) {
let output = ''
let forcasts = weather.list.slice(1, 5)
forcasts.forEach(forcast => {
output += `
<div class="forcast__box">
<span>${forcast.dt_txt}</span>
<ul>
<li>${forcast.weather[0].description}</li>
<li>${forcast.main.humidity}</li>
<li>${forcast.main.pressure}</li>
<li>${forcast.main.temp}</li>
<li>${forcast.main.humidity}</li>
</ul>
</div> `
})
document.getElementById('forcast').innerHTML = output;
$('.forcast').slick('resize');
}
}
export const ui = new UI()
slickjs
$(document).ready(function() {
$('.forcast').slick({
autoplay: false,
autoplaySpeed: 4000,
slidesToShow: 3,
slidesToScroll: 3,
dots: false,
arrows: false,
responsive: [{
breakpoint: 990,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
}, {
breakpoint: 550,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
});
})
将您的 slickSettings 保存在一个全局变量中(实际上是在一个随处可用的变量中,您需要初始化一个 slick 实例):
$(window).on('load', function() {
window.slickSettings = {
autoplay: false,
... // <= rest of your slick settings
};
$('.forcast').slick(window.slickSettings);
})
...并且,在您的 ajax 调用中,使用相同的设置重新初始化 slick:
... { ...
document.getElementById('forcast').innerHTML = output;
$('.forcast').slick(window.slickSettings); // <= add this line
...
}
注意:你不需要真的需要污染window
对象 属性 并且您的设置很可能只存在于一个单独的变量中,但是,由于我对您的系统一无所知,所以上面的设置肯定会起作用。通常,您希望避免向 window 对象添加属性,并尝试将变量的范围限制在完成工作所需的范围内。
另一种选择是在更新 html 后在 window
上触发 resize
事件。不在 .forcast
上! resize
事件不会冒泡,只能放在 window
对象上:
Only handlers registered on the window object will receive events.
仔细查看示例页面,您有 slickAdd
方法:
$('.forcast').slick('slickAdd',output);
...但要实现此功能 output
只需要额外的幻灯片。
这似乎也有效:
$('.forcast')[0].slick.refresh();
您可以在将标记插入 DOM 以强制 slick 重新初始化后手动触发调整大小事件
$('.forcast').slick('resize');
或者等待 slick.js 初始化,直到 DOM 创建完成。
现在你在 $(document).ready()
上初始化 slick,它在 ajax 调用完成之前被调用。