Compare commits
2 Commits
c85615797b
...
8961d8c629
| Author | SHA1 | Date | |
|---|---|---|---|
| 8961d8c629 | |||
| 38da294879 |
376
script.js
376
script.js
@@ -399,8 +399,8 @@ const indexedDBStorage = {
|
|||||||
const request = index.getAll();
|
const request = index.getAll();
|
||||||
request.onsuccess = () => {
|
request.onsuccess = () => {
|
||||||
const images = request.result || [];
|
const images = request.result || [];
|
||||||
// 按时间戳排序
|
// 按时间戳倒序排序(最新的在前)
|
||||||
images.sort((a, b) => a.timestamp - b.timestamp);
|
images.sort((a, b) => b.timestamp - a.timestamp);
|
||||||
resolve(images.map(img => ({
|
resolve(images.map(img => ({
|
||||||
id: img.imageId,
|
id: img.imageId,
|
||||||
url: img.url
|
url: img.url
|
||||||
@@ -797,7 +797,7 @@ const uiController = {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
gallery.appendChild(imageDiv);
|
gallery.insertBefore(imageDiv, gallery.firstChild);
|
||||||
|
|
||||||
// 添加事件监听器
|
// 添加事件监听器
|
||||||
const viewLargeBtn = imageDiv.querySelector('.view-large-btn');
|
const viewLargeBtn = imageDiv.querySelector('.view-large-btn');
|
||||||
@@ -805,6 +805,9 @@ const uiController = {
|
|||||||
const copyBtn = imageDiv.querySelector('.copy-url-btn');
|
const copyBtn = imageDiv.querySelector('.copy-url-btn');
|
||||||
const removeBtn = imageDiv.querySelector('.remove-btn');
|
const removeBtn = imageDiv.querySelector('.remove-btn');
|
||||||
|
|
||||||
|
// 添加移动端触摸交互
|
||||||
|
this.addMobileTouchInteraction(imageDiv);
|
||||||
|
|
||||||
if (viewLargeBtn) {
|
if (viewLargeBtn) {
|
||||||
viewLargeBtn.addEventListener('click', (e) => {
|
viewLargeBtn.addEventListener('click', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -833,8 +836,8 @@ const uiController = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加到内存中的图像记录
|
// 添加到内存中的图像记录(插入到最前面)
|
||||||
generatedImages.push({ id: imageId, url: imageUrl });
|
generatedImages.unshift({ id: imageId, url: imageUrl });
|
||||||
|
|
||||||
// 显示"全部下载"按钮
|
// 显示"全部下载"按钮
|
||||||
this.updateDownloadAllButtonVisibility();
|
this.updateDownloadAllButtonVisibility();
|
||||||
@@ -868,7 +871,7 @@ const uiController = {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
gallery.appendChild(placeholderDiv);
|
gallery.insertBefore(placeholderDiv, gallery.firstChild);
|
||||||
return placeholderDiv;
|
return placeholderDiv;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -911,6 +914,9 @@ const uiController = {
|
|||||||
const copyBtn = placeholder.querySelector('.copy-url-btn');
|
const copyBtn = placeholder.querySelector('.copy-url-btn');
|
||||||
const removeBtn = placeholder.querySelector('.remove-btn');
|
const removeBtn = placeholder.querySelector('.remove-btn');
|
||||||
|
|
||||||
|
// 添加移动端触摸交互
|
||||||
|
this.addMobileTouchInteraction(placeholder);
|
||||||
|
|
||||||
if (viewLargeBtn) {
|
if (viewLargeBtn) {
|
||||||
viewLargeBtn.addEventListener('click', (e) => {
|
viewLargeBtn.addEventListener('click', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -939,8 +945,8 @@ const uiController = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加到内存中的图像记录
|
// 添加到内存中的图像记录(插入到最前面)
|
||||||
generatedImages.push({ id: imageId, url: imageUrl });
|
generatedImages.unshift({ id: imageId, url: imageUrl });
|
||||||
|
|
||||||
// 显示"全部下载"按钮
|
// 显示"全部下载"按钮
|
||||||
this.updateDownloadAllButtonVisibility();
|
this.updateDownloadAllButtonVisibility();
|
||||||
@@ -1012,137 +1018,59 @@ const uiController = {
|
|||||||
|
|
||||||
// 设置删除按钮功能
|
// 设置删除按钮功能
|
||||||
if (deleteButton) {
|
if (deleteButton) {
|
||||||
deleteButton.onclick = function() {
|
deleteButton.onclick = async () => {
|
||||||
// 保存当前图像ID
|
|
||||||
const currentImageId = generatedImages[currentImageIndex].id;
|
const currentImageId = generatedImages[currentImageIndex].id;
|
||||||
|
await app.removeGeneratedImage(currentImageId);
|
||||||
|
|
||||||
// 删除当前图像
|
|
||||||
app.removeGeneratedImage(currentImageId).then(() => {
|
|
||||||
// 检查删除后是否还有图像
|
|
||||||
if (generatedImages.length === 0) {
|
|
||||||
// 没有图像了,关闭模态框
|
|
||||||
currentModalInstance.hide();
|
|
||||||
} else {
|
|
||||||
// 更新当前图像索引
|
|
||||||
if (currentImageIndex >= generatedImages.length) {
|
|
||||||
// 如果删除的是最后一张,显示上一张
|
|
||||||
currentImageIndex = generatedImages.length - 1;
|
|
||||||
}
|
|
||||||
// 如果索引仍然有效,显示图像
|
|
||||||
if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) {
|
|
||||||
modalImage.src = generatedImages[currentImageIndex].url;
|
|
||||||
// 更新删除按钮对应的图像ID
|
|
||||||
deleteButton.onclick = function() {
|
|
||||||
const newCurrentImageId = generatedImages[currentImageIndex].id;
|
|
||||||
app.removeGeneratedImage(newCurrentImageId).then(() => {
|
|
||||||
// 再次检查删除后是否还有图像
|
|
||||||
if (generatedImages.length === 0) {
|
if (generatedImages.length === 0) {
|
||||||
currentModalInstance.hide();
|
currentModalInstance.hide();
|
||||||
} else {
|
} else {
|
||||||
// 更新当前图像索引
|
// 调整索引
|
||||||
if (currentImageIndex >= generatedImages.length) {
|
if (currentImageIndex >= generatedImages.length) {
|
||||||
currentImageIndex = generatedImages.length - 1;
|
currentImageIndex = generatedImages.length - 1;
|
||||||
}
|
}
|
||||||
// 如果索引仍然有效,显示图像
|
|
||||||
|
// 重新加载当前图像
|
||||||
if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) {
|
if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) {
|
||||||
modalImage.src = generatedImages[currentImageIndex].url;
|
modalImage.src = generatedImages[currentImageIndex].url;
|
||||||
// 更新删除按钮对应的图像ID
|
|
||||||
deleteButton.onclick = arguments.callee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新翻页按钮状态
|
this.updateNavigationButtons();
|
||||||
uiController.updateNavigationButtons();
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置翻页按钮功能
|
// 设置翻页按钮功能
|
||||||
if (prevButton) {
|
if (prevButton) {
|
||||||
prevButton.onclick = function() {
|
prevButton.onclick = () => {
|
||||||
if (currentImageIndex > 0) {
|
this.navigateToImage(-1);
|
||||||
currentImageIndex--;
|
|
||||||
modalImage.src = generatedImages[currentImageIndex].url;
|
|
||||||
// 更新删除按钮对应的图像ID
|
|
||||||
deleteButton.onclick =async function() {
|
|
||||||
// 保存当前图像ID
|
|
||||||
const currentImageId = generatedImages[currentImageIndex].id;
|
|
||||||
|
|
||||||
// 删除当前图像
|
|
||||||
await app.removeGeneratedImage(currentImageId);
|
|
||||||
|
|
||||||
// 检查删除后是否还有图像
|
|
||||||
if (generatedImages.length === 0) {
|
|
||||||
// 没有图像了,关闭模态框
|
|
||||||
currentModalInstance.hide();
|
|
||||||
} else {
|
|
||||||
// 更新当前图像索引
|
|
||||||
if (currentImageIndex >= generatedImages.length) {
|
|
||||||
// 如果删除的是最后一张,显示上一张
|
|
||||||
currentImageIndex = generatedImages.length - 1;
|
|
||||||
}
|
|
||||||
// 如果索引仍然有效,显示图像
|
|
||||||
if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) {
|
|
||||||
modalImage.src = generatedImages[currentImageIndex].url;
|
|
||||||
// 更新删除按钮对应的图像ID
|
|
||||||
deleteButton.onclick = arguments.callee;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新翻页按钮状态
|
|
||||||
uiController.updateNavigationButtons();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextButton) {
|
if (nextButton) {
|
||||||
nextButton.onclick = function() {
|
nextButton.onclick = () => {
|
||||||
if (currentImageIndex < generatedImages.length - 1) {
|
this.navigateToImage(1);
|
||||||
currentImageIndex++;
|
|
||||||
modalImage.src = generatedImages[currentImageIndex].url;
|
|
||||||
// 更新删除按钮对应的图像ID
|
|
||||||
deleteButton.onclick = function() {
|
|
||||||
// 保存当前图像ID
|
|
||||||
const currentImageId = generatedImages[currentImageIndex].id;
|
|
||||||
|
|
||||||
// 删除当前图像
|
|
||||||
app.removeGeneratedImage(currentImageId).then(() => {
|
|
||||||
// 检查删除后是否还有图像
|
|
||||||
if (generatedImages.length === 0) {
|
|
||||||
// 没有图像了,关闭模态框
|
|
||||||
currentModalInstance.hide();
|
|
||||||
} else {
|
|
||||||
// 更新当前图像索引
|
|
||||||
if (currentImageIndex >= generatedImages.length) {
|
|
||||||
// 如果删除的是最后一张,显示上一张
|
|
||||||
currentImageIndex = generatedImages.length - 1;
|
|
||||||
}
|
|
||||||
// 如果索引仍然有效,显示图像
|
|
||||||
if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) {
|
|
||||||
modalImage.src = generatedImages[currentImageIndex].url;
|
|
||||||
// 更新删除按钮对应的图像ID
|
|
||||||
deleteButton.onclick = arguments.callee;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新翻页按钮状态
|
|
||||||
uiController.updateNavigationButtons();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新翻页按钮状态
|
// 更新翻页按钮状态
|
||||||
this.updateNavigationButtons();
|
this.updateNavigationButtons();
|
||||||
|
|
||||||
|
// 添加键盘事件监听器
|
||||||
|
this.addModalKeyboardListeners();
|
||||||
|
|
||||||
|
// 添加触摸事件监听器
|
||||||
|
this.addModalTouchListeners(modalImage);
|
||||||
|
|
||||||
// 创建并显示模态框
|
// 创建并显示模态框
|
||||||
currentModalInstance = new bootstrap.Modal(modalElement);
|
currentModalInstance = new bootstrap.Modal(modalElement);
|
||||||
|
|
||||||
|
// 添加模态框关闭事件监听器
|
||||||
|
modalElement.addEventListener('hidden.bs.modal', () => {
|
||||||
|
this.removeModalKeyboardListeners();
|
||||||
|
this.removeModalTouchListeners(modalImage);
|
||||||
|
});
|
||||||
|
|
||||||
currentModalInstance.show();
|
currentModalInstance.show();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1162,15 +1090,232 @@ const uiController = {
|
|||||||
const prevButton = document.getElementById('prevImageBtn');
|
const prevButton = document.getElementById('prevImageBtn');
|
||||||
const nextButton = document.getElementById('nextImageBtn');
|
const nextButton = document.getElementById('nextImageBtn');
|
||||||
|
|
||||||
|
// 如果有多张图片,始终显示翻页按钮(因为支持循环导航)
|
||||||
if (prevButton) {
|
if (prevButton) {
|
||||||
prevButton.style.display = currentImageIndex > 0 ? 'block' : 'none';
|
prevButton.style.display = generatedImages.length > 1 ? 'block' : 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextButton) {
|
if (nextButton) {
|
||||||
nextButton.style.display = currentImageIndex < generatedImages.length - 1 ? 'block' : 'none';
|
nextButton.style.display = generatedImages.length > 1 ? 'block' : 'none';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 添加模态框键盘事件监听器
|
||||||
|
addModalKeyboardListeners: function() {
|
||||||
|
// 移除之前的监听器(如果存在)
|
||||||
|
this.removeModalKeyboardListeners();
|
||||||
|
|
||||||
|
// 添加键盘事件监听器
|
||||||
|
this.modalKeyboardHandler = (e) => {
|
||||||
|
if (!currentModalInstance || !document.getElementById('imageViewerModal').classList.contains('show')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(e.key) {
|
||||||
|
case 'ArrowLeft':
|
||||||
|
case 'ArrowUp':
|
||||||
|
e.preventDefault();
|
||||||
|
this.navigateToImage(-1);
|
||||||
|
break;
|
||||||
|
case 'ArrowRight':
|
||||||
|
case 'ArrowDown':
|
||||||
|
e.preventDefault();
|
||||||
|
this.navigateToImage(1);
|
||||||
|
break;
|
||||||
|
case 'Escape':
|
||||||
|
e.preventDefault();
|
||||||
|
currentModalInstance.hide();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('keydown', this.modalKeyboardHandler);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 移除模态框键盘事件监听器
|
||||||
|
removeModalKeyboardListeners: function() {
|
||||||
|
if (this.modalKeyboardHandler) {
|
||||||
|
document.removeEventListener('keydown', this.modalKeyboardHandler);
|
||||||
|
this.modalKeyboardHandler = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 添加模态框触摸事件监听器
|
||||||
|
addModalTouchListeners: function(modalImage) {
|
||||||
|
if (!modalImage) return;
|
||||||
|
|
||||||
|
// 移除之前的监听器(如果存在)
|
||||||
|
this.removeModalTouchListeners(modalImage);
|
||||||
|
|
||||||
|
let startX = 0;
|
||||||
|
let startY = 0;
|
||||||
|
let isMoving = false;
|
||||||
|
const minSwipeDistance = 50; // 最小滑动距离
|
||||||
|
const maxVerticalDistance = 100; // 最大垂直距离,超过则不视为翻页
|
||||||
|
|
||||||
|
this.modalTouchStartHandler = (e) => {
|
||||||
|
if (e.touches.length === 1) {
|
||||||
|
startX = e.touches[0].clientX;
|
||||||
|
startY = e.touches[0].clientY;
|
||||||
|
isMoving = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.modalTouchMoveHandler = (e) => {
|
||||||
|
if (e.touches.length === 1) {
|
||||||
|
isMoving = true;
|
||||||
|
// 防止默认滚动行为
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.modalTouchEndHandler = (e) => {
|
||||||
|
if (isMoving && e.changedTouches.length === 1) {
|
||||||
|
const endX = e.changedTouches[0].clientX;
|
||||||
|
const endY = e.changedTouches[0].clientY;
|
||||||
|
const deltaX = endX - startX;
|
||||||
|
const deltaY = endY - startY;
|
||||||
|
|
||||||
|
// 检查是否为有效的水平滑动
|
||||||
|
if (Math.abs(deltaX) > minSwipeDistance && Math.abs(deltaY) < maxVerticalDistance) {
|
||||||
|
if (deltaX > 0) {
|
||||||
|
// 向右滑动 - 上一张图片
|
||||||
|
this.navigateToImage(-1);
|
||||||
|
} else {
|
||||||
|
// 向左滑动 - 下一张图片
|
||||||
|
this.navigateToImage(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isMoving = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
modalImage.addEventListener('touchstart', this.modalTouchStartHandler, { passive: false });
|
||||||
|
modalImage.addEventListener('touchmove', this.modalTouchMoveHandler, { passive: false });
|
||||||
|
modalImage.addEventListener('touchend', this.modalTouchEndHandler, { passive: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
// 移除模态框触摸事件监听器
|
||||||
|
removeModalTouchListeners: function(modalImage) {
|
||||||
|
if (!modalImage) return;
|
||||||
|
|
||||||
|
if (this.modalTouchStartHandler) {
|
||||||
|
modalImage.removeEventListener('touchstart', this.modalTouchStartHandler);
|
||||||
|
this.modalTouchStartHandler = null;
|
||||||
|
}
|
||||||
|
if (this.modalTouchMoveHandler) {
|
||||||
|
modalImage.removeEventListener('touchmove', this.modalTouchMoveHandler);
|
||||||
|
this.modalTouchMoveHandler = null;
|
||||||
|
}
|
||||||
|
if (this.modalTouchEndHandler) {
|
||||||
|
modalImage.removeEventListener('touchend', this.modalTouchEndHandler);
|
||||||
|
this.modalTouchEndHandler = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导航到指定图片
|
||||||
|
navigateToImage: function(direction) {
|
||||||
|
if (generatedImages.length <= 1) return;
|
||||||
|
|
||||||
|
let newIndex = currentImageIndex + direction;
|
||||||
|
|
||||||
|
// 循环导航
|
||||||
|
if (newIndex < 0) {
|
||||||
|
newIndex = generatedImages.length - 1;
|
||||||
|
} else if (newIndex >= generatedImages.length) {
|
||||||
|
newIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentImageIndex = newIndex;
|
||||||
|
|
||||||
|
// 更新图片
|
||||||
|
const modalImage = document.getElementById('viewerModalImage');
|
||||||
|
const deleteButton = document.getElementById('viewerDeleteImage');
|
||||||
|
|
||||||
|
if (modalImage && generatedImages[currentImageIndex]) {
|
||||||
|
modalImage.src = generatedImages[currentImageIndex].url;
|
||||||
|
|
||||||
|
// 更新删除按钮对应的图像ID
|
||||||
|
if (deleteButton) {
|
||||||
|
deleteButton.onclick = async function() {
|
||||||
|
const currentImageId = generatedImages[currentImageIndex].id;
|
||||||
|
await app.removeGeneratedImage(currentImageId);
|
||||||
|
|
||||||
|
if (generatedImages.length === 0) {
|
||||||
|
currentModalInstance.hide();
|
||||||
|
} else {
|
||||||
|
if (currentImageIndex >= generatedImages.length) {
|
||||||
|
currentImageIndex = generatedImages.length - 1;
|
||||||
|
}
|
||||||
|
if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) {
|
||||||
|
modalImage.src = generatedImages[currentImageIndex].url;
|
||||||
|
deleteButton.onclick = arguments.callee;
|
||||||
|
}
|
||||||
|
uiController.updateNavigationButtons();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新导航按钮状态
|
||||||
|
this.updateNavigationButtons();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 添加移动端触摸交互
|
||||||
|
addMobileTouchInteraction: function(imageElement) {
|
||||||
|
if (!imageElement) return;
|
||||||
|
|
||||||
|
let touchTimeout = null;
|
||||||
|
let isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
||||||
|
|
||||||
|
if (!isTouchDevice) return; // 非触摸设备不需要添加此交互
|
||||||
|
|
||||||
|
// 添加触摸开始事件
|
||||||
|
const touchStartHandler = (e) => {
|
||||||
|
// 清除之前的超时
|
||||||
|
if (touchTimeout) {
|
||||||
|
clearTimeout(touchTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加touched类
|
||||||
|
imageElement.classList.add('touched');
|
||||||
|
|
||||||
|
// 设置超时,3秒后自动移除touched类
|
||||||
|
touchTimeout = setTimeout(() => {
|
||||||
|
imageElement.classList.remove('touched');
|
||||||
|
}, 3000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加点击外部移除touched类的逻辑
|
||||||
|
const documentClickHandler = (e) => {
|
||||||
|
if (!imageElement.contains(e.target)) {
|
||||||
|
imageElement.classList.remove('touched');
|
||||||
|
if (touchTimeout) {
|
||||||
|
clearTimeout(touchTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 绑定事件
|
||||||
|
imageElement.addEventListener('touchstart', touchStartHandler, { passive: true });
|
||||||
|
imageElement.addEventListener('click', touchStartHandler); // 也支持点击
|
||||||
|
|
||||||
|
// 存储清理函数,以便后续清理
|
||||||
|
imageElement._cleanupMobileTouch = () => {
|
||||||
|
imageElement.removeEventListener('touchstart', touchStartHandler);
|
||||||
|
imageElement.removeEventListener('click', touchStartHandler);
|
||||||
|
document.removeEventListener('click', documentClickHandler);
|
||||||
|
if (touchTimeout) {
|
||||||
|
clearTimeout(touchTimeout);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加到全局点击监听器(延迟添加避免立即触发)
|
||||||
|
setTimeout(() => {
|
||||||
|
document.addEventListener('click', documentClickHandler);
|
||||||
|
}, 100);
|
||||||
|
},
|
||||||
|
|
||||||
// 显示图像预览
|
// 显示图像预览
|
||||||
displayImagePreview: function(imageData) {
|
displayImagePreview: function(imageData) {
|
||||||
const preview = document.getElementById('imagePreview');
|
const preview = document.getElementById('imagePreview');
|
||||||
@@ -1321,7 +1466,7 @@ const uiController = {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
gallery.appendChild(imageDiv);
|
gallery.appendChild(imageDiv); // 由于数据库查询已经是倒序,这里用appendChild保持顺序
|
||||||
|
|
||||||
// 添加事件监听器
|
// 添加事件监听器
|
||||||
const viewLargeBtn = imageDiv.querySelector('.view-large-btn');
|
const viewLargeBtn = imageDiv.querySelector('.view-large-btn');
|
||||||
@@ -1329,6 +1474,9 @@ const uiController = {
|
|||||||
const copyBtn = imageDiv.querySelector('.copy-url-btn');
|
const copyBtn = imageDiv.querySelector('.copy-url-btn');
|
||||||
const removeBtn = imageDiv.querySelector('.remove-btn');
|
const removeBtn = imageDiv.querySelector('.remove-btn');
|
||||||
|
|
||||||
|
// 添加移动端触摸交互
|
||||||
|
this.addMobileTouchInteraction(imageDiv);
|
||||||
|
|
||||||
if (viewLargeBtn) {
|
if (viewLargeBtn) {
|
||||||
viewLargeBtn.addEventListener('click', (e) => {
|
viewLargeBtn.addEventListener('click', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -1373,6 +1521,10 @@ const uiController = {
|
|||||||
imageElements.forEach(element => {
|
imageElements.forEach(element => {
|
||||||
const removeBtn = element.querySelector('.remove-btn');
|
const removeBtn = element.querySelector('.remove-btn');
|
||||||
if (removeBtn && removeBtn.dataset.imageId == imageId) {
|
if (removeBtn && removeBtn.dataset.imageId == imageId) {
|
||||||
|
// 清理移动端触摸事件监听器
|
||||||
|
if (element._cleanupMobileTouch) {
|
||||||
|
element._cleanupMobileTouch();
|
||||||
|
}
|
||||||
element.remove();
|
element.remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
127
styles.css
127
styles.css
@@ -239,6 +239,57 @@ body {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 移动端触摸设备优化 */
|
||||||
|
@media (hover: none) and (pointer: coarse) {
|
||||||
|
/* 在触摸设备上,overlay始终可见但透明度较低 */
|
||||||
|
.image-overlay {
|
||||||
|
opacity: 0.3;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 点击时显示完整overlay */
|
||||||
|
.image-item:active .image-overlay,
|
||||||
|
.image-item.touched .image-overlay {
|
||||||
|
opacity: 1;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为触摸设备添加点击提示 */
|
||||||
|
.image-item::after {
|
||||||
|
content: "轻触显示操作";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 8px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
color: white;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0.6;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item.touched::after {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 在小屏幕设备上也应用类似效果 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.image-overlay {
|
||||||
|
opacity: 0.4;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item:active .image-overlay,
|
||||||
|
.image-item.touched .image-overlay {
|
||||||
|
opacity: 1;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 状态指示器 */
|
/* 状态指示器 */
|
||||||
.status-indicator {
|
.status-indicator {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -434,6 +485,21 @@ body {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 模态框图片触摸优化 */
|
||||||
|
#viewerModalImage {
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
touch-action: pan-x pan-y;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewerModalImage:active {
|
||||||
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 翻页按钮样式 */
|
/* 翻页按钮样式 */
|
||||||
@@ -471,6 +537,33 @@ body {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 触摸反馈 */
|
||||||
|
.modal-fullscreen .modal-body .btn-light:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端响应式样式 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.modal-fullscreen .modal-body .btn-light {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#prevImageBtn {
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nextImageBtn {
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为触摸设备优化图片显示 */
|
||||||
|
#viewerModalImage {
|
||||||
|
touch-action: manipulation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 图像查看模态框特定样式 */
|
/* 图像查看模态框特定样式 */
|
||||||
#imageViewerModal .modal-content {
|
#imageViewerModal .modal-content {
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
@@ -512,6 +605,40 @@ body {
|
|||||||
.btn-grid-row .btn {
|
.btn-grid-row .btn {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
min-height: 36px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端按钮优化 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.btn-grid {
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-grid-row {
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-grid-row .btn {
|
||||||
|
min-height: 44px; /* 增加触摸目标大小 */
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 触摸设备专用样式 */
|
||||||
|
@media (hover: none) and (pointer: coarse) {
|
||||||
|
.btn-grid-row .btn {
|
||||||
|
min-height: 48px; /* 更大的触摸目标 */
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 10px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-grid-row .btn:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 错误状态 */
|
/* 错误状态 */
|
||||||
|
|||||||
Reference in New Issue
Block a user