朋友们,美好的一天!代替介绍(问题陈述)
这一切都开始与其他人的滑块(在网络上现成的解决方案,如研究bxslider,owlcarousel和光滑)。有一天,我将撰写有关使用这些工具的详细教程(美梦)。有一种写滑块的愿望。但是,很快(包括在阅读有关Habré的几篇文章后),人们意识到只有滑块才是w夫。需要一些更激进的东西。结果,我提出了以下任务:编写带有内置滑块的自适应图库生成器。条件:- 能够上传任意数量的图像(从硬盘上的任何位置)。
- 画廊由上载的图像组成,标记是根据HTML5语义“即时”形成的。
- 在不同分辨率的屏幕上,图库看起来同样不错。
- 当您单击任何图像时,将生成一个滑块。
- 生成滑块时,背景变暗。
- 单击的图像是第一张幻灯片。
- 幻灯片切换是通过DOM实现的。
- 滑动开关平稳。
- 使用按钮和键盘控制幻灯片切换的能力。
- 通过单击当前幻灯片和按钮以及使用键盘可以返回画廊。
- 纯JavaScript(所有标记都通过JS)。
- 最小代码。
所以,让我们走(正如加加林所说的,去太空)。标记如下所示:<div class="wrap">
<input type="file" multiple accept="image/*">
<button>generate gallery</button>
</div>
在有趣的事情中,也许是输入标签的multiple和accept属性。第一个属性允许您上传多个文件,第二个属性-对可以下载的文件类型设置过滤器。在这种情况下,accept的值为“ image / *”,这意味着只能上传图像(任意)。立即带来美丽(添加样式):* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
background: radial-gradient(circle, skyblue, steelblue);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
button {
padding: 0.25em;
font-family: monospace;
text-transform: uppercase;
cursor: pointer;
}
.darken {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
z-index: -1;
}
.slider {
width: 100%;
display: inherit;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
figure {
margin: 0.5em;
width: 300px;
display: inherit;
flex-direction: column;
justify-content: center;
align-items: center;
transition: 0.2s;
}
figcaption {
font-size: 1.2em;
text-transform: capitalize;
text-align: center;
margin-bottom: 0.25em;
color: #ddd;
text-shadow: 1px 1px rgba(0, 0, 0, 0.4);
}
img {
max-width: 80%;
max-height: 80vh;
cursor: pointer;
}
.button {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 30px;
background: none;
border: none;
outline: none;
filter: invert();
}
.left {
left: 2em;
}
.right {
right: 2em;
}
.close {
top: 2em;
right: 1em;
}
没有什么可谈的(.darken-变暗)。继续...到JS。我们找到按钮并将监听器挂在其上:let button = document.querySelector("button");
button.addEventListener("click", generateGallery);
所有进一步的代码将在generateGallery函数中,以避免“未定义”而不返回:function generateGallery() {
}
我们找到输入,检查它是否为空,获取下载文件的集合,删除.wrap并为图库创建一个容器:let input = document.querySelector("input");
if(input.files.length == 0) return;
let files = input.files;
let i;
let wrap = document.querySelector(".wrap");
document.body.removeChild(wrap);
let slider = document.createElement("div");
slider.className = "slider";
document.body.appendChild(slider);
我们对文件集合进行排序,获取每个文件的名称和地址,创建标记,创建图像标题和图像本身:for (i = 0; i < files.length; i++) {
let file = files[i];
let name = file.name;
let src = `img/${name}`;
let figure = document.createElement("figure");
slider.appendChild(figure);
let figcaption = document.createElement("figcaption");
let regexp = /.+(?=\.)/;
name = name.match(regexp);
figcaption.innerText = name[0];
figure.appendChild(figcaption);
let img = document.createElement("img");
img.src = src;
figure.appendChild(img);
}
我们想在单击图像时生成一个滑块。为此,我们找到整个图形并将其挂在每个侦听器上:let figures = document.querySelectorAll("figure");
for (i = 0; i < figures.length; i++) {
let figure = figures[i];
figure.addEventListener("click", () => {
generateSlider(figure);
});
}
接下来,我们在generateSlider函数内部进行工作:function generateSlider(figure) {
}
调暗背景:darkenBack();
function darkenBack() {
if (document.querySelector(".darken") == null) {
let div = document.createElement("div");
div.className = "darken";
document.body.appendChild(div);
} else {
let div = document.querySelector(".darken");
document.body.removeChild(div);
}
}
我们将一次显示一张幻灯片。不要忘记滑动开关应该平滑。通过透明性和较小的过渡,这很容易实现。因此,我们将图像叠加在一起,将它们放置在中间,并使所有图像(“单击”的图像除外)透明:for (i = 0; i < figures.length; i++) {
if (figures[i].hasAttribute("style")) {
figures[i].removeAttribute("style");
} else {
figures[i].setAttribute("style", "margin: 0; width: auto; position: absolute; opacity: 0;");
}
}
if (figure.hasAttribute("style")) {
figure.style.opacity = 1;
generateButtons();
} else generateButtons();
接下来,创建按钮以切换幻灯片并关闭图库。结果是很长很枯燥的代码(也许每次启动滑块时都生成按钮不是一个好主意):按钮创建代码:function generateButtons() {
if (document.querySelector(".buttons") == null) {
let buttons = document.createElement("div");
buttons.className = "buttons";
slider.appendChild(buttons);
let leftButton = document.createElement("button");
leftButton.className = "button left";
let leftImg = document.createElement("img");
leftImg.src = "https://thebestcode.ru/media/sliderGenerator/buttons/left.png";
leftButton.appendChild(leftImg);
buttons.appendChild(leftButton);
leftButton.addEventListener("click", () => changeSlide("-"));
let rightButton = document.createElement("button");
rightButton.className = "button right";
let rightImg = document.createElement("img");
rightImg.src = "https://thebestcode.ru/media/sliderGenerator/buttons/right.png";
rightButton.appendChild(rightImg);
buttons.appendChild(rightButton);
rightButton.addEventListener("click", () => changeSlide("+"));
let closeButton = document.createElement("button");
closeButton.className = "button close";
let closeImg = document.createElement("img");
closeImg.src = "https://thebestcode.ru/media/sliderGenerator/buttons/close.png";
closeButton.appendChild(closeImg);
buttons.appendChild(closeButton);
closeButton.addEventListener("click", () => generateSlider(figure));
} else {
let buttons = document.querySelector(".buttons");
slider.removeChild(buttons);
}
}
切换幻灯片是使用changeSlide函数实现的,该函数分别作为参数“ +”或“-”传递:function changeSlide(e) {
for (i = 0; i < figures.length; i++) {
figures[i].style.opacity = 0;
}
if (e == "-") {
if (figure == figures[0]) {
figure = figures[figures.length - 1];
} else {
figure = figure.previousElementSibling;
}
} else if (e == "+") {
if (figure == figures[figures.length - 1]) {
figure = figures[0];
} else {
figure = figure.nextElementSibling;
}
}
figure.style.opacity = 1;
}
添加使用键盘切换幻灯片和关闭图库的功能:document.addEventListener("keydown", e => {
if (e.keyCode == 37 || e.keyCode == 189) {
changeSlide("-");
} else if (e.keyCode == 39 || e.keyCode == 187) {
changeSlide("+");
} else if(e.keyCode == 27) {
generateSlider(figure);
}
});
到此,带有内置滑块的自适应图库生成器已准备就绪。任务完成。满足条件。最后,我意识到“最小代码”和“使用JS即时形成所有标记”相互矛盾,但是为时已晚(道歉还为时已晚还是“一个共和国”呢?)。结果可以在这里看到。请注意,在Codepen上,我们使用URL.createObjectURL链接到图像,因为Codepen看不到img文件夹。感谢您的关注。