如何不使用全局变量选择选择器中的最新或最旧元素?
无需全局变量选择最新/最旧弹窗元素的方案
你提的这个问题很关键!确实,因为弹窗可能被插入到mainArea的前后不同位置,直接用.last()或.first()根本没法准确拿到最新创建或最旧创建的元素——毕竟DOM节点顺序和创建顺序已经脱节了。不用全局变量的话,我们可以通过给每个弹窗标记创建时间的方式来解决,这里有两种实用的方案:
方案一:用自定义数据属性存储时间戳
每次克隆弹窗时,给它添加一个data-created属性,值为当前的毫秒级时间戳(确保唯一性)。之后要找最新/最旧弹窗,只需要通过这个属性排序即可。
修改你的代码如下:
popupWindow = $( '<div class="popup">' + ( '<button class="close">Close</button>' + '<div class="work-area"></div>' ) + '</div>' ); mainArea = $('.work-area'); $('#show-back').on('click', function() { // 克隆时添加时间戳属性 popupWindow.clone() .data('created', Date.now()) .insertBefore(mainArea); drawOnLatest(); // 替换原方法,改为操作最新弹窗 }); $('#show-front').on('click', function() { popupWindow.clone() .data('created', Date.now()) .insertAfter(mainArea); drawOnLatest(); }); $('body').on('click', '.close', function() { $(this).parent().remove(); }); // 获取最新弹窗的工具函数 function getLatestPopup() { let latest = null; let latestTime = 0; $('.popup').each(function() { const createdTime = $(this).data('created'); if (createdTime > latestTime) { latestTime = createdTime; latest = $(this); } }); return latest; } // 获取最旧弹窗的工具函数 function getOldestPopup() { let oldest = null; let oldestTime = Infinity; $('.popup').each(function() { const createdTime = $(this).data('created'); if (createdTime < oldestTime) { oldestTime = createdTime; oldest = $(this); } }); return oldest; } // 示例:操作最新弹窗的逻辑 function drawOnLatest() { const latestPopup = getLatestPopup(); if (latestPopup) { // 这里写你要对最新弹窗执行的操作,比如操作它的work-area latestPopup.find('.work-area').text('This is the latest popup'); } }
方案二:数组排序简化写法
如果觉得遍历弹窗有点繁琐,也可以把弹窗转为数组后直接排序,写法更简洁:
// 获取最新弹窗的简洁写法 const getLatestPopup = () => { return $('.popup').toArray().sort((a, b) => { return $(b).data('created') - $(a).data('created'); })[0]; }; // 获取最旧弹窗的简洁写法 const getOldestPopup = () => { return $('.popup').toArray().sort((a, b) => { return $(a).data('created') - $(b).data('created'); })[0]; };
方案优势说明
时间戳Date.now()返回的是当前时间的毫秒数,每次创建弹窗时这个值都是唯一且递增的,所以不管弹窗插在DOM的哪个位置,我们都能通过这个标记准确找到创建时间最早或最晚的那个,完全不需要全局变量来跟踪。
如果担心极端情况下同一毫秒创建多个弹窗的精度问题,可以改用performance.now(),它能提供微秒级的精度,几乎不会出现重复。
内容的提问来源于stack exchange,提问作者Nadroev
相关产品推荐
相关产品推荐

