水平無縫循環滾動:圖片從右向左移動,滑鼠懸停暫停,移出繼續,首尾無縫銜接。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ImageScroll.aspx.cs" Inherits="ImageScroll" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>圖片無縫滾動展示</title>
<style>
.scroll-container {
width: 441px; height: 130px;
overflow: hidden;
border: 1px solid #ddd;
position: relative;
background: #f5f5f5 url('Images/img2/32.jpg') no-repeat center;
}
.scroll-track {
position: absolute; left: 0; top: 0; white-space: nowrap;
}
.scroll-item {
display: inline-block;
width: 140px; /* 圖片寬 + 間距 */
text-align: center;
vertical-align: top;
margin-right: 10px;
}
.scroll-item img { width: 120px; height: 90px; border: 1px solid #ccc; border-radius: 4px; }
.scroll-item a { display: block; margin-top: 5px; color: #333; text-decoration: none; font-size: 12px; }
.scroll-item a:hover { color: #0066cc; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="scroll-container" id="scrollContainer">
<div class="scroll-track" id="scrollTrack">
<asp:DataList ID="dlImages" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow">
<ItemTemplate>
<div class="scroll-item">
<asp:HyperLink ID="hlkImage" runat="server"
NavigateUrl='<%# "Detail.aspx?id=" + Eval("ID") %>'>
<asp:Image ID="imgThumb" runat="server"
ImageUrl='<%# Eval("Spic") %>'
AlternateText='<%# Eval("Type") %>'
Width="120" Height="90" />
</asp:HyperLink>
<asp:HyperLink ID="hlkTitle" runat="server"
NavigateUrl='<%# "Detail.aspx?id=" + Eval("ID") %>'
Text='<%# Eval("Type") %>' CssClass="item-title" />
</div>
</ItemTemplate>
</asp:DataList>
<!-- 關鍵:複製一份內容實現無縫循環 -->
<div id="scrollTrackClone" class="scroll-track" style="display:none;"></div>
</div>
</div>
</form>
<script>
(function() {
var container = document.getElementById('scrollContainer');
var track = document.getElementById('scrollTrack');
var clone = document.getElementById('scrollTrackClone');
var speed = 20; // 毫秒/步,數值越大越慢
var step = 1; // 每步像素
var timer = null;
var isPaused = false;
// 複製內容到 clone 實現無縫
function duplicateContent() {
clone.innerHTML = track.innerHTML;
clone.style.display = 'inline-block';
// 將 clone 附加到 track 後方 (同一父容器)
track.parentNode.appendChild(clone);
}
function scroll() {
if (isPaused) return;
// 當原始內容完全滾出視口,重置 scrollLeft 到 0 (瞬間跳回開頭,視覺上無縫)
if (container.scrollLeft >= track.scrollWidth) {
container.scrollLeft = 0;
} else {
container.scrollLeft += step;
}
}
function start() { timer = setInterval(scroll, speed); }
function stop() { clearInterval(timer); }
container.onmouseover = function() { isPaused = true; };
container.onmouseout = function() { isPaused = false; };
duplicateContent();
start();
})();
</script>
</body>
</html>
public partial class ImageScroll : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) BindData();
}
void BindData()
{
// 實際專案從 DAL/BLL 獲取資料
var data = HotelDAL.KeFangServices.SelectInfo(); // 你的資料存取方法
dlImages.DataSource = data;
dlImages.DataBind();
}
}
public class KeFangServices
{
public static List SelectInfo()
{
var list = new List();
string sql = "SELECT TOP 20 ID, Type, Spic FROM Rooms WHERE IsShow=1 ORDER BY SortOrder";
using (var conn = new SqlConnection(ConnStr))
using (var cmd = new SqlCommand(sql, conn))
{
conn.Open();
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
list.Add(new RoomInfo {
ID = dr.GetInt32(0),
Type = dr.GetString(1),
Spic = dr.GetString(2) // 縮圖相對路徑
});
}
}
}
return list;
}
}
public class RoomInfo
{
public int ID { get; set; }
public string Type { get; set; }
public string Spic { get; set; } // 如 "~/Images/Rooms/101_thumb.jpg"
}
| 技術點 | 實作方式 |
|---|---|
| 無縫循環 | 複製一份完整內容緊接原內容後,當 scrollLeft ≥ 原內容寬度時瞬間歸零 |
| 水平排版 | DataList `RepeatDirection="Horizontal" RepeatLayout="Flow"` + CSS `display:inline-block; white-space:nowrap` |
| 滾動控制 | `setInterval` 修改 `container.scrollLeft`,非 `transform` 避免重繪問題 |
| 暫停/繼續 | `onmouseover`/`onmouseout` 控制旗標,不清除 timer 避免抖動 |
| 響應式適配 | 容器寬度用 % 或 vw,JS 計算寬度時用 `offsetWidth`/`scrollWidth` |
<marquee direction="left" scrollamount="2" scrolldelay="20"
onmouseover="this.stop()" onmouseout="this.start()">
<!-- 內容 -->
</marquee>
❌ 不符合 HTML5 標準、無法精確控制、無無縫循環、無響應式、無觸控支援。**請勿在新專案使用。**
DataList + CSS + 原生 JS 實現的無縫滾動,輕量、可控、相容性佳,是 ASP.NET WebForms 時代展示型滾動元件的經典最佳實踐。