我在D3 v4中写了一个小灯箱,点击三张图片加载:选中的一个,上一组和下一组。
我将这些图像的引用存储在与general update pattern一起使用的数组中。然后,在单击“上一个”或“下一个”按钮时,将修改数组,以便添加一个图像并在任一端删除一个图像:
[image1, image2, image3]
> '下一个'> [image2, image3, image4]
[image1, image2, image3]
> 'prev'> [image99, image1, image2]
换句话说,一个图像应该“退出”,两个应该“更新”,一个应该“进入”。在视觉上,它应该是这样的:
不幸的是,它不能按设计工作,我不知道为什么。在控制台中,我看到两个'退出',一个'更新'和两个'进入'。为什么呢?
这是我的pen,相关的代码块如下。感谢任何帮助。
d3.selectAll( 'div[role="img"]' ) // image group for lightbox
.on( "mousedown touchstart", function( d, i, n ) {
luxBox( d, i, n );
});
function luxBox( d, idx, n ) {
var l = n.length,
j = idx, //selected image in group
jp = j > 0 ? j - 1 : l - 1, //preceding image in group
jn = j < l - 1 ? j + 1 : 0; //following image in group
var imgs = [
d3.select(n[jp]), //0
d3.select(n[j]), //1
d3.select(n[jn]) //2
];
function update(data) {
var t = d3.transition().duration(400);
var lux = d3.select('#luxbox')
.attr("class", "show")
.select('#slider')
.selectAll('li')
.data(data, function(d) { return d; }); //join
lux //exit
.exit()
.attr("class", "exit")
.transition(t)
.style("opacity", function(d, i) {
console.log('exit: i=' + i);
return 0;
})
.remove();
lux //update
.attr("class", "update")
.transition(t)
.style("transform", function(d, i) {
console.log( 'update: i=' + i );
return "translateX(" + (i * 100 - 100) + "%)";
});
lux //enter
.enter()
.append('li')
.attr("class", "enter")
.style("opacity", 0)
.style("background-image", function(d) { return d.style('background-image'); })
.style("transform", function(d, i) {
console.log( 'enter: i=' + i );
return "translateX(" + (i * 100 - 100) + "%)";
})
//append("h3") // caption
.transition(t)
.style("opacity", 1);
}
update(imgs);
d3.select(".next")
.on("mousedown touchstart", function() {
idx < l - 1 ? idx++ : idx = 0; //next index
console.log( 'index=' + idx );
jn = idx < l - 1 ? idx + 1 : 0; //new following image
imgs.push( d3.select(n[jn]) );
imgs.shift();
update( imgs );
});
d3.select(".prev")
.on("mousedown touchstart", function() {
idx > 0 ? idx-- : idx = l - 1; //prev index
console.log( 'index=' + idx );
jp = idx > 0 ? idx - 1 : l - 1; //new preceding image
imgs.unshift( d3.select(n[jp]) );
imgs.pop();
update( imgs );
});
d3.select(".close")
.on("mousedown touchstart", function() {
d3.select('#luxbox')
.attr("class", "hide");
setTimeout( function() {
d3.selectAll('#slider li').remove();
console.log('slides removed')
}, 400 );
});
}
答案 0 :(得分:3)
在进一步调查并找到一些great answers后,我通过使用匹配图像选择索引的数据 key 解决了我的问题。
var imgs = [
{
"url": d3.select(n[jp]).select("img").attr("src"),
"caption": d3.select(n[jp]).select("img").attr("alt"),
"key": jp
},
{
"url": d3.select(n[j]).select("img").attr("src"),
"caption": d3.select(n[j]).select("img").attr("alt"),
"key": j
},
{
"url": d3.select(n[jn]).select("img").attr("src"),
"caption": d3.select(n[jn]).select("img").attr("alt"),
"key": jn
}
];
// ...
.data(data, function(d) { return d.key; }); //join