JavaScript函数初始加载不执行仅窗口Resize生效(需等待元素)
问题说明
开发网页时需实现以下布局逻辑:
- 屏幕宽度**<1200px**时,将
hdSmElement从Splide轮播中移出,作为独立标题区展示 - 屏幕宽度≥1200px时,将
hdSmElement重新插回轮播的原始位置
当前代码存在两个问题:
- 页面初始加载时不会执行元素迁移,仅窗口Resize时生效
- 等待Splide动态生成元素的逻辑存在偏差,可能导致操作时机不对
现有代码:
function waitForElement(selector, callback) { var element = document.querySelector(selector); if (element) { callback(element); } else { setTimeout(function() { waitForElement(selector, callback); }, 100); } } document.addEventListener("DOMContentLoaded", function() { var hdSmElement = document.querySelector('.sp__h .hd__sm'); var splideList = document.querySelector('.sp .splide__list'); var hdElWrapper = document.querySelector('.sp__h'); var wrapper = document.querySelector('.sp__wr'); var originalParent = hdSmElement.parentElement; function moveHdSmElement() { console.log("Checking elements..."); if (!hdSmElement) { console.error('hdSmElement not found'); return; } if (!splideList) { console.error('splideList not found'); return; } if (!wrapper) { console.error('wrapper not found'); return; } if (window.innerWidth < 1200) { wrapper.appendChild(hdSmElement); splideList.append(hdElWrapper); } else if (window.innerWidth >= 1200) { originalParent.appendChild(hdSmElement); } } waitForElement('.sp__h .hd__sm .splide__slide__row .sp__wr', function(){ console.log("Found element"); moveHdSmElement(); }); window.addEventListener('resize', moveHdSmElement); });
修复方案
修改后的完整代码
function waitForElement(selector, callback) { const element = document.querySelector(selector); if (element) { callback(element); } else { setTimeout(() => waitForElement(selector, callback), 100); } } document.addEventListener("DOMContentLoaded", function() { // 初始化变量,避免提前获取未生成的元素 let hdSmElement; let splideList; let hdElWrapper; let wrapper; let originalParent; function moveHdSmElement() { // 每次执行前重新获取元素,确保动态生成后能拿到最新引用 hdSmElement = document.querySelector('.sp__h .hd__sm'); splideList = document.querySelector('.sp .splide__list'); hdElWrapper = document.querySelector('.sp__h'); wrapper = document.querySelector('.sp__wr'); // 完善元素存在性检查 if (!hdSmElement) { console.error('hdSmElement 未找到'); return; } if (!splideList) { console.error('splideList 未找到'); return; } if (!wrapper) { console.error('wrapper 未找到'); return; } if (!hdElWrapper) { console.error('hdElWrapper 未找到'); return; } // 仅首次获取时记录原始父元素 if (!originalParent) { originalParent = hdSmElement.parentElement; } // 仅当元素不在目标位置时执行DOM操作,避免重复操作 if (window.innerWidth < 1200) { if (hdSmElement.parentElement !== wrapper) { wrapper.appendChild(hdSmElement); } if (hdElWrapper.parentElement !== splideList) { splideList.appendChild(hdElWrapper); } } else { if (hdSmElement.parentElement !== originalParent) { originalParent.appendChild(hdSmElement); } } } // 等待Splide核心元素加载完成(选择.splide__list确保轮播已初始化) waitForElement('.sp .splide__list', function() { console.log("Splide元素已加载,执行初始布局调整"); // 初始加载时立即执行一次迁移逻辑 moveHdSmElement(); }); // Resize事件添加防抖,避免频繁触发DOM操作 let resizeTimeout; window.addEventListener('resize', function() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(moveHdSmElement, 100); }); });
关键修改点
- 延迟元素获取:把元素选择逻辑放到
moveHdSmElement内部,确保每次执行都能拿到最新的DOM元素,避免动态生成后引用失效 - 触发初始执行:等待到Splide核心元素后立即调用
moveHdSmElement,解决初始加载不执行的问题 - 避免重复DOM操作:添加父元素判断,只有元素不在目标位置时才执行append操作,减少不必要的DOM变动
- Resize防抖:添加100ms防抖,避免窗口拖动时频繁触发DOM操作影响性能
- 完善错误检测:增加
hdElWrapper的存在性检查,提升代码健壮性
内容的提问来源于stack exchange,提问作者Pointless
相关产品推荐
相关产品推荐

