
本文详细介绍了如何使用jquery和`window.matchmedia()`实现响应式marquee效果,确保在移动设备(屏幕宽度小于768px)上自动初始化marquee插件,而在桌面设备上(屏幕宽度大于等于768px)自动销毁。通过结合`data-*`属性进行状态管理,避免了插件重复初始化或销毁导致的错误,提供了一个健壮且性能优化的解决方案。
在现代网页设计中,为了提供最佳的用户体验,许多交互元素需要根据设备的屏幕尺寸进行动态调整。Marquee(跑马灯)效果作为一种常见的文本或图片滚动展示方式,在移动设备上可能有助于节省空间并吸引用户注意力,但在桌面设备上则可能显得冗余或分散注意力。因此,实现一个能在移动端初始化、在桌面端销毁的响应式Marquee功能变得尤为重要。
核心实现原理
要实现这一功能,我们需要解决两个主要问题:
- 实时检测屏幕宽度变化:准确判断当前设备是移动端还是桌面端。
- 管理Marquee插件状态:避免在插件未初始化时尝试销毁,或在已初始化时重复初始化。
本教程将结合jQuery库、jQuery.Marquee插件、window.matchMedia() API以及HTML data-* 属性来构建一个稳定可靠的解决方案。
准备工作
首先,确保你的项目中已引入jQuery库和jQuery.Marquee插件。你可以通过CDN或本地文件引入它们:
接下来,定义一个用于展示Marquee内容的HTML元素。例如:
这是需要滚动的文本内容。请调整浏览器窗口大小,观察Marquee效果的变化。 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
响应式Marquee逻辑实现
我们将使用window.matchMedia()来监听屏幕宽度的变化,并利用元素的data-*属性来跟踪Marquee插件的初始化状态。
1. 使用 window.matchMedia() 进行媒体查询
window.matchMedia()是一个强大的API,允许我们在JavaScript中执行CSS媒体查询。它返回一个MediaQueryList对象,其中包含matches属性(一个布尔值,指示当前文档是否匹配媒体查询)和addListener()方法(用于监听媒体查询状态的变化)。
jQuery($ => { // 确保DOM加载完毕且 $ 别名可用
// 定义媒体查询:当屏幕宽度小于768px时匹配
const m768 = matchMedia("(width < 768px)");
// 获取需要应用Marquee效果的元素
const $listings = $('.tt-services-listing');
// 定义Marquee插件的配置选项
const marqueeOptions = {
duration: 20000, // 滚动持续时间
duplicated: true, // 是否复制内容以实现无缝滚动
delayBeforeStart: 0, // 开始前的延迟
startVisible: true, // 开始时是否可见
};
// 定义处理Marquee初始化和销毁的函数
const handleMarquee = () => {
// 如果当前屏幕宽度小于768px (移动端) 且 Marquee尚未初始化
if (m768.matches && !$listings.data("marqueeinit")) {
// 设置 data-marqueeinit 属性为1,表示已初始化
$listings.data("marqueeinit", 1);
// 初始化Marquee插件
$listings.marquee(marqueeOptions);
}
// 如果当前屏幕宽度大于等于768px (桌面端) 且 Marquee已初始化
else if (!m768.matches && $listings.data("marqueeinit")) {
// 移除 data-marqueeinit 属性,表示已销毁
$listings.removeData("marqueeinit");
// 销毁Marquee插件
$listings.marquee("destroy");
}
};
// 监听窗口大小变化事件,每次变化时调用 handleMarquee 函数
$(window).on("resize", handleMarquee);
// 页面加载时立即执行一次 handleMarquee,以根据初始屏幕宽度设置Marquee状态
handleMarquee();
});2. 代码详解
- jQuery($ => { ... });: 这是jQuery的一种简写方式,确保在DOM加载完毕后执行代码,并且$符号在函数作用域内指向jQuery对象,避免与其他库的冲突。
- const m768 = matchMedia("(width : 创建一个MediaQueryList对象,用于检测屏幕宽度是否小于768像素。
- const $listings = $('.tt-services-listing');: 缓存jQuery对象,提高性能。
- marqueeOptions: 定义了Marquee插件的配置。你可以根据需求调整这些参数。
-
handleMarquee() 函数:
- m768.matches && !$listings.data("marqueeinit"): 这个条件判断当前是否处于移动端 (m768.matches 为 true) 并且Marquee插件尚未在该元素上初始化 ($listings.data("marqueeinit") 为 undefined 或 falsey)。
- $listings.data("marqueeinit", 1);: 如果满足初始化条件,我们通过jQuery的data()方法在元素上设置一个自定义数据属性data-marqueeinit。这个属性充当一个标志,记录Marquee是否已经初始化。
- $listings.marquee(marqueeOptions);: 调用Marquee插件进行初始化。
- !m768.matches && $listings.data("marqueeinit"): 这个条件判断当前是否处于桌面端 (!m768.matches 为 true) 并且Marquee插件已在该元素上初始化 ($listings.data("marqueeinit") 为 true 或 truthy)。
- $listings.removeData("marqueeinit");: 如果满足销毁条件,移除data-marqueeinit属性,清除初始化标志。
- $listings.marquee("destroy");: 调用Marquee插件的destroy方法来销毁它。
- $(window).on("resize", handleMarquee);: 绑定resize事件监听器。当浏览器窗口大小改变时,handleMarquee函数会被调用。
- handleMarquee();: 在脚本加载和DOM准备就绪后立即调用一次handleMarquee,以确保在页面加载时就根据当前屏幕尺寸正确设置Marquee状态。
注意事项与最佳实践
避免重复操作:原始代码中的问题在于,在resize事件中没有检查Marquee是否已经初始化或销毁,导致可能在已初始化的情况下重复初始化,或在未初始化的情况下尝试销毁,从而引发错误。通过data-marqueeinit属性进行状态管理完美解决了这个问题。
-
window.matchMedia() 的优势:
- 性能优化:相较于在resize事件中频繁读取$(window).width(),matchMedia更高效,因为它只在媒体查询状态真正改变时才更新其matches属性,并且可以监听这些变化。
- 语义化:直接使用CSS媒体查询的语法,代码更清晰易懂。
-
Debounce resize 事件 (可选):尽管matchMedia本身已经很高效,但如果你有其他复杂的逻辑也在resize事件中执行,考虑使用防抖(debounce)技术来限制handleMarquee函数被调用的频率,进一步优化性能。例如:
let resizeTimer; $(window).on("resize", () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(handleMarquee, 200); // 200ms 延迟 }); 插件路径:确保jquery.marquee.min.js的CDN链接是正确的。email protected] 这种格式通常是防止爬虫的,实际使用时应替换为正确的CDN路径,例如https://cdn.jsdelivr.net/npm/jquery.marquee@1.6.0/jquery.marquee.min.js。
总结
通过结合window.matchMedia()进行响应式判断和data-*属性进行状态管理,我们可以优雅地实现jQuery Marquee插件在不同屏幕尺寸下的动态初始化和销毁。这种方法不仅解决了常见的重复初始化或销毁错误,还提供了一个性能更优、代码更清晰的解决方案,是实现复杂响应式交互的有效实践。










