如何用jQuery为数组中的每6个项目添加HTML



我正在尝试使用jQuery生成打印大小的页面,每个页面包含6张图像,并继续创建这些页面,直到目录中的所有图像都已通过。

我现在拥有的是保存HTML字符串的var,保存目录中每个文件的文件名的数组,以及将img src设置为URL的$.each循环,并将文件名连接到它的末尾。

两个问题:

  1. 如下所示,我有一个if/else语句通过使用小于或大于符号来确定图像的数量,但这不是很可扩展,因为如果目录中有超过18个文件,代码就会停止。我如何使这个循环动态?

  2. 当我调用append函数时,HTML正在追加,但它没有添加更改的img源,我在哪里出错了?

代码如下:

$('#get-files-btn').on('click', function() {

var html = '<div class="page" style="min-height: 10in; max-height: 10in; min-width: 8.5in; max-width: 8.5in; background-color:green"><div class="row row-cols-2 g-3 mx-3 mt-0"><div class="col mt-0"><img class="img-fluid img-1" src="" ><p class="mt-1 mb-1 text-center">Description 1</p></div><div class="col mt-0 pt-0"><img class="img-fluid img-2" src="" ><p class="mt-1 mb-1 text-center">Description 1</p></div><div class="col mt-0 pt-0"><img class="img-fluid img-43" src="" ><p class="mt-1 mb-1 text-center">Description 1</p></div><div class="col mt-0 pt-0"><img class="img-fluid img-4" src="" ><p class="mt-1 mb-1 text-center">Description 1</p></div><div class="col mt-0 pt-0"><img class="img-fluid img-5" src="" ><p class="mt-1 mb-1 text-center">Description 1</p></div><div class="col mt-0 pt-0"><img class="img-fluid img-6" src="" ><p class="mt-1 mb-1 text-center">Description 1</p></div></div></div>'
$.ajax({
method: 'POST',
url: '/public/operations/getFilenames',
data: {
get_files: true,
},
success: function(response) {
response = JSON.parse(response);
let files = [];
$(response).each(function(index) {
if (response[index] != '.' && response[index] != '..') {
files.push(response[index]);
}
});
let count = 0;
var page_html = $(html).html();
$(files).each(function(index) {

if (index < 6) {
console.log(files[index]);
$(page_html).find('.img-1').attr('src', 'MY URL/temp/' + files[0]);
$(page_html).find('.img-2').attr('src', 'MY URL/temp/' + files[1]);
$(page_html).find('.img-3').attr('src', 'MY URL/temp/' + files[2]);
$(page_html).find('.img-4').attr('src', 'MY URL/temp/' + files[3]);
$(page_html).find('.img-5').attr('src', 'MY URL/temp/' + files[4]);
$(page_html).find('.img-6').attr('src', 'MY URL/temp/' + files[5]);
} else if (index >= 6 && index < 12) {
console.log(files[index]);
//more code here
} else if (index >= 12 && index < 18) {
console.log(files[index]);
//more code here
}
});

$('#pages-col').append(page_html);
}
})
})

我不能完全确定我做对了,因为在你的代码中有一些奇怪的决定。无论如何,为了尽可能保持原样,我做了一些努力来集成从ajax请求中检索到的文件数组的适当呈现。

这是核心部分:

//render the files loading the template and setting the src attr of its first 6 images
function renderFiles(files) {
const basedir = '/temp/';
const picturesBlock = $('#mytemplate')[0].content.cloneNode(true);
$(files).each(function(index, file) {
if (index < 6) {
$(picturesBlock).find(`.img-${index+1}`).attr('src', `${basedir}/${file}`);
}
console.log(file);
});
$('#pages-col').append(picturesBlock);
}

这是一个函数,当files数组准备好处理时将被调用,它将只是克隆模板#mytemplate(我决定定义你拥有的长html字符串作为模板,以便更容易维护)设置6个图像的src属性作为url来自files数组中的前6个位置。

https://api.jquery.com/jquery.each/

传递给each的回调函数可以接受两个参数(index,value),这样你就可以跟踪索引和当前迭代的值(..

我还推断了.page容器的内联样式,以便它保留在为.page选择器保留的css规则中。你的样式容器有一个固定的高度和宽度与绿色背景。如果你问自己为什么#pages-col内容会溢出它的容器,请记住这一点。

另外,为了演示,我注释掉了做ajax请求的部分,我只是直接调用renderFiles函数,传递一个具有8个文件名的伪造数组。还要考虑到我将basedir值放在函数内部的自己的变量中,并且在构建src url时,它将被添加到文件值中。

function renderFiles(files, pageSize) {
const groupsOfFiles = splitIntoGroups(files, pageSize);
console.log(groupsOfFiles);
$(groupsOfFiles).each(function(index, groupOfFiles) {
renderPage(groupOfFiles, 'pageTemplate', $('#pages-col'));
});
}
function splitIntoGroups(arr, groupSize) {
let groups = [];
for (let i = 0; i < arr.length; i += groupSize) {
let group = arr.slice(i, i + groupSize);
groups.push(group);
}
return groups;
}
function renderPage(imageUrls, pageTemplateId, target, basedir = '/temp/'){
let currentPage = $(`#${pageTemplateId}`)[0].content.cloneNode(true);
$(imageUrls).each(function(index, file) {
console.log(`processed url: ${file}`);
$(currentPage)
.find(`.img-${index+1}`)
.attr('src', `/${basedir}/${file}`);
});
$(target).append(currentPage);
}
$('#get-files-btn').on('click', function() {
const files = [
'file1.jpg',
'file2.jpg',
'file3.jpg',
'file4.jpg',
'file5.jpg',
'file6.jpg',
'file7.jpg',
'file8.jpg'
];
renderFiles(files, 6);
/*
$.ajax({
method: 'POST',
url: '/public/operations/getFilenames',
data: {
get_files: true,
},
success: function(response) {
response = JSON.parse(response);

let files = [];
$(response).each(function(index) {
if (response[index] != '.' && response[index] != '..') {
files.push(response[index]);
}
});
//here you should call renderFiles(files);
}
});
*/
})
.page {
min-height: 10in;
max-height: 10in;
min-width: 8.5in;
max-width: 8.5in;
background-color: green;
}
button{
cursor: pointer;
}
/*this rule was added just to show the contrast between 1st and 2nd page*/
#pages-col > .page:nth-child(even) {
background: red !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<template id="pageTemplate">
<div class="page">
<div class="row row-cols-2 g-3 mx-3 mt-0">
<div class="col mt-0">
<img class="img-fluid img-1" src="">
<p class="mt-1 mb-1 text-center">Description 1</p>
</div>
<div class="col mt-0 pt-0">
<img class="img-fluid img-2" src="">
<p class="mt-1 mb-1 text-center">Description 2</p>
</div>
<div class="col mt-0 pt-0">
<img class="img-fluid img-3" src="">
<p class="mt-1 mb-1 text-center">Description 3</p>
</div>
<div class="col mt-0 pt-0">
<img class="img-fluid img-4" src="">
<p class="mt-1 mb-1 text-center">Description 4</p>
</div>
<div class="col mt-0 pt-0">
<img class="img-fluid img-5" src="">
<p class="mt-1 mb-1 text-center">Description 5</p>
</div>
<div class="col mt-0 pt-0">
<img class="img-fluid img-6" src="">
<p class="mt-1 mb-1 text-center">Description 6</p>
</div>
</div>
</div>
</template>
<div id="pages-col"></div>
<button id="get-files-btn">Get Files</button>

更好的方法:

这是一种更好的方法,它使用两个不同的模板:一个用于页面容器,另一个用于具有图像的单个项。如果您希望更改页面大小或希望对项目进行总体样式设置,而不是根据其位置对每个项目进行样式设置,则此策略更适用。当然,你可以在顶部添加css规则,以解决每个单独的.col项或每个单独的.page,就像我在演示中所做的那样,我可以覆盖甚至页面的背景色。

此策略还可以更好地处理最后一组文件可能无法填充整个6个条目槽的事实。因此,这些图像将完全不呈现,而不是空图像。

function renderFiles(files, pageSize) {
const groupsOfFiles = splitIntoGroups(files, pageSize);
$(groupsOfFiles).each(function(index, groupOfFiles) {
renderPage(groupOfFiles, 'pageTemplate', $('#pages-col'));
});
}
function splitIntoGroups(arr, groupSize) {
let groups = [];
for (let i = 0; i < arr.length; i += groupSize) {
let group = arr.slice(i, i + groupSize);
groups.push(group);
}
return groups;
}
function renderPage(imageUrls, pageTemplateId, target, basedir = '/temp/') {
let currentPage = $(`#${pageTemplateId}`)[0].content.cloneNode(true);
$(imageUrls).each(function(index, imageUrl) {
console.log(`processed url: ${imageUrl}`);
renderImage(imageUrl, 'imageTemplate', $(currentPage).find('.row'), index+1, basedir);
});
$(target).append(currentPage);
}
function renderImage(imageUrl, imageTemplateId, target, imageIndex, basedir){
debugger;
const image = $(`#${imageTemplateId}`)[0].content.cloneNode(true);
const imageEl = $(image).find('img');
$(imageEl).attr('src', `/${basedir}/${imageUrl}`)
$(imageEl).addClass(`img-${imageIndex}`);
$(image).find('p').text(`Description ${imageIndex}`);
$(target).append(image);
}
$('#get-files-btn').on('click', function() {
const files = [
'file1.jpg',
'file2.jpg',
'file3.jpg',
'file4.jpg',
'file5.jpg',
'file6.jpg',
'file7.jpg',
'file8.jpg'
];
renderFiles(files, 6);

})
.page {
min-height: 10in;
max-height: 10in;
min-width: 8.5in;
max-width: 8.5in;
background-color: green;
}
button {
cursor: pointer;
}

/*this rule was added just to show the contrast between 1st and 2nd page*/
#pages-col > .page:nth-child(even) {
background: red !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>

<template id="imageTemplate">
<div class="col mt-0 pt-0">
<img class="img-fluid" src="">
<p class="mt-1 mb-1 text-center"></p>
</div>
</template>
<template id="pageTemplate">
<div class="page">
<div class="row row-cols-2 g-3 mx-3 mt-0">
</div>
</div>
</template>
<div id="pages-col"></div>
<button id="get-files-btn">Get Files</button>

最新更新