如何在jQuery代码中使用来自JavaScript的变量?关于音频自动淡出按钮的实现咨询
如何在jQuery代码中使用来自JavaScript的变量?关于音频自动淡出按钮的实现咨询
嘿,我看了你这段音频自动淡出按钮的代码,先帮你梳理下现有写法里的小问题,再告诉你怎么更合理地在jQuery里使用变量~
首先,你现在的代码里有个没必要的冗余点:在onclick事件里嵌套$(document).ready()完全没必要,毕竟点击按钮的时候DOM肯定已经加载完成了,这个嵌套会让逻辑变绕。
先把你原有的代码格式化出来,方便咱们对照:
<input type="button" id="autofadebtn<?php echo $track;?>" value="Fade Out" onclick="$(document).ready(function() { $('#<?php echo $track;?>')[0].volume = .5; $('#<?php echo $track;?>').animate({volume: 0}, 30000); }); $('#<?php echo $track;?>').promise().done(function() { $('#<?php echo $track;?>').trigger('pause'); });"
接下来给你优化一下,分成两步来写,逻辑会清晰很多:
第一步:优化按钮的HTML结构,把track值存到自定义属性里
<input type="button" id="autofadebtn<?php echo $track;?>" value="Fade Out" data-track="<?php echo $track;?>" class="autofade-btn">
这里用data-track属性存了当前的track标识,同时给所有淡出按钮加了统一的class,这样不用给每个按钮都写一堆重复的onclick代码,后续维护也方便。
第二步:用jQuery批量绑定事件,优雅使用变量
// 页面加载完成后绑定事件,只需要写一次 $(function() { $('.autofade-btn').on('click', function() { // 从当前点击的按钮上拿到track变量 const trackId = $(this).data('track'); // 获取对应的音频元素 const audioElement = $('#' + trackId)[0]; // 先把音量设为0.5,再开始30秒的淡出动画 audioElement.volume = 0.5; $(audioElement).animate({volume: 0}, 30000) .promise() .done(function() { // 动画完成后暂停音频 audioElement.pause(); }); }); });
这样写的好处有这些:
- 把JS逻辑和HTML结构分离开了,代码更整洁,不会把事件逻辑混在标签里
- 通过
data-*属性获取变量,避免了重复输出PHP代码,逻辑更清晰 - 用统一的class绑定事件,不管你有多少个音频轨道,都能自动生效
- 去掉了多余的
$(document).ready()嵌套,执行效率更高
另外要提个小细节:jQuery默认的animate方法是不支持volume属性动画的,如果发现淡出效果没生效,你可以先扩展一下jQuery的动画支持,加这段代码就行:
// 先保存原生的animate方法 const originalAnimate = $.fn.animate; // 扩展animate,支持音量渐变 $.fn.animate = function(prop, speed, easing, callback) { if (prop.volume !== undefined) { return this.each(function() { const audio = this; const startVolume = audio.volume; const volumeChange = prop.volume - startVolume; const duration = speed || 400; const startTime = new Date().getTime(); function updateVolume() { const elapsedTime = new Date().getTime() - startTime; const progress = Math.min(elapsedTime / duration, 1); audio.volume = startVolume + volumeChange * progress; if (progress < 1) { requestAnimationFrame(updateVolume); } else { if (callback) callback.call(audio); } } updateVolume(); }); } // 其他属性还是用原生的animate处理 return originalAnimate.apply(this, arguments); };
备注:内容来源于stack exchange,提问作者Andrew Helme
相关产品推荐
相关产品推荐

