javascript - Isotope & javascript - 添加新元素后元素不再可点击
问题描述
我正在尝试制作一个从 json 加载的图像表(不是真正的 json,更像是 javascript 数组),并且每次 json 更改时(当我使用一些脚本将新图像附加到 json 文件时,我想要那个我的图片表也要上传。
这是json格式:
[{
"image": "images/set_1_UTC+03.jpg",
"weight": 101
}, {
"image": "images/set_1_UTC+03.jpg",
"weight": 102
}, {
"image": "images/set_1_UTC+03.jpg",
"weight": 103
}, {
"image": "images/set_1_UTC+03.jpg",
"weight": 104
}]
为此,我使用同位素。我设法实现了我上面提到的一切,唯一的问题是我想让图像可点击,每当我点击其中一张图片时,它的尺寸会更大,当我再次点击它以恢复到小尺寸时. 这是代码:
<script>
var previous = 0;
var current = 0;
loadJSON(function(response) {
// Parse JSON string into object
current = JSON.parse(response);
});
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'data.json', true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
let lengthOfprevious = previous.length;
setInterval(function() {
loadJSON(function(response) {
// Parse JSON string into object
current = JSON.parse(response);
});
previous = current;
if (lengthOfprevious != current.length) {
UpdateBody(lengthOfprevious);
}
lengthOfprevious = previous.length;
}, 5000);
function UpdateBody(startIndex) {
var newElements = "";
for (let i = startIndex; i < previous.length; i++) {
$(document).ready(function() {
newElements = "";
newElements +=
'<div class="photo element-item">' +
'<a href="' + previous[i].image + '"><img class="small-image" src="' + previous[i].image + '"/></a>' +
'<a class="weight">' + previous[i].weight + '</a></div>';
var $newElems = $(newElements);
$('#container').append($newElems).imagesLoaded(function() {
$('#container').isotope('insert', $newElems);
});
});
}
// ============//
$(function() {
var $container = $('#container'),
$photos = $container.find('.photo'),
$loadingIndicator = $('<div class="loading"><span><img src="http://i.imgur.com/IE7iw.gif" /></span></div>');
// trigger Isotope after images have loaded
$container.imagesLoaded(function() {
$container.isotope({
itemSelector: '.photo',
masonry: {
columnWidth: 200
}
});
});
// shows the large version of the image
// shows small version of previously large image
function enlargeImage($photo) {
$photos.filter('.large').removeClass('large');
$photo.addClass('large');
$container.isotope('reLayout');
}
$photos.find('a').click(function() {
var $this = $(this),
$photo = $this.parents('.photo');
if ($photo.hasClass('large')) {
// already large, just remove
$photo.removeClass('large');
$container.isotope('reLayout');
} else {
if ($photo.hasClass('has-big-image')) {
enlargeImage($photo);
} else {
// add a loading indicator
$this.append($loadingIndicator);
// create big image
var $bigImage = $('<img>', {
src: this.href
});
// give it a wrapper and appended it to element
$('<div>', {
'class': 'big-image'
})
.append($bigImage)
.appendTo($this)
.imagesLoaded(function() {
$loadingIndicator.remove()
enlargeImage($photo);
});
// add a class, so we'll know not to do this next time
$photo.addClass('has-big-image');
}
}
return false;
});
});
}
</script>
问题是 setInterval 运行一次后,一切都按预期工作,当它再次运行时,图像不再可点击。如果我在 for 中移动 // ============// 标记之后的部分,则只有最后一个图像是可点击的。
我无法找出解决方案(我是 javascript 的初学者)。有人可以指出我正确的方向吗?
更新:在这里您可以获取项目的存档,以便可以在本地运行它。
您需要手动复制和粘贴数据文件中的一些行以使演示工作,因为它会搜索数据文件的先前状态和当前状态的差异。问题是它一开始是可以点击的,然后就不能点击了。
解决方案
我在您的代码中发现了一些需要修改的地方:
- 为什么
$(document).ready
使用超过1次? - 无需使用
$(function()
因为我看到照片类是在运行时动态生成的,并且容器类已经在 DOM 中,所以我修改了点击事件
$container.on('click', '.photo a', function() {
编辑请注意代码未经测试;我刚刚对它进行了代码纠正。
最终更新代码如下:
var previous = 0;
var current = 0;
loadJSON(function(response) {
// Parse JSON string into object
current = JSON.parse(response);
});
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'data.json', true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
let lengthOfprevious = previous.length;
setInterval(function() {
loadJSON(function(response) {
// Parse JSON string into object
current = JSON.parse(response);
});
previous = current;
if (lengthOfprevious != current.length) {
UpdateBody(lengthOfprevious);
}
lengthOfprevious = previous.length;
}, 5000);
function UpdateBody(startIndex) {
var newElements = "",
$container = $('#container'),
$photos = $container.find('.photo'),
$loadingIndicator = $('<div class="loading"><span><img src="http://i.imgur.com/IE7iw.gif" /></span></div>');
$(document).ready(function() {
for (let i = startIndex; i < previous.length; i++) {
newElements = "";
newElements +=
'<div class="photo element-item">' +
'<a href="' + previous[i].image + '"><img class="small-image" src="' + previous[i].image + '"/></a>' +
'<a class="weight">' + previous[i].weight + '</a></div>';
var $newElems = $(newElements);
$container.append($newElems).imagesLoaded(function() {
$container.isotope('insert', $newElems);
});
}
$container.imagesLoaded(function() {
$container.isotope({
itemSelector: '.photo',
masonry: {
columnWidth: 200
}
});
});
// shows the large version of the image
// shows small version of previously large image
function enlargeImage($photo) {
$photos.filter('.large').removeClass('large');
$photo.addClass('large');
$container.isotope('reLayout');
}
$container.on('click', '.photo a', function() {
var $this = $(this),
$photo = $this.parents('.photo');
if ($photo.hasClass('large')) {
// already large, just remove
$photo.removeClass('large');
$container.isotope('reLayout');
} else {
if ($photo.hasClass('has-big-image')) {
enlargeImage($photo);
} else {
// add a loading indicator
$this.append($loadingIndicator);
// create big image
var $bigImage = $('<img>', {
src: this.href
});
// give it a wrapper and appended it to element
$('<div>', {
'class': 'big-image'
})
.append($bigImage)
.appendTo($this)
.imagesLoaded(function() {
$loadingIndicator.remove()
enlargeImage($photo);
});
// add a class, so we'll know not to do this next time
$photo.addClass('has-big-image');
}
}
return false;
});
});
}
推荐阅读
- c++ - 如何修复 C4251“X 需要有 dll 接口才能被 Y 类的客户端使用”?
- python - 静态文件不能在 django 中工作,但我的设置与我过去做过的另一个项目相同吗?
- mod-rewrite - 删除子目录
- swift - 结合日期和字符串的哈希
- javascript - 用jquery检测光标是否在定义的区域
- android - Android:如何使用 VirtualDisplay 在 WallpaperService 中托管 WebView?
- wordpress - 如何更改 Wordpress 密码重置电子邮件?
- java - ParseServer:不保存用户信息?
- c# - 如何将用户控件中的初始化值返回到表单
- docker - 在 docker 容器中安装 libnode-dev