我有一个有Wordpress网站的客户。在站点上,他们有一个从API获取的课程列表(ul元素)。
这个课程列表是没有排序的,唯一的方法就是使用一些定制的JS。我已经制作了JS脚本,它对列表进行了完美的排序。
问题是,当抓取完成后,我想运行这个脚本。他们也有一个按钮,将获取更多的项目,然后我需要重新排序的列表。
我不能在body标记上使用onLoad,因为在抓取完成之前已经完成了加载。我可以使用setInterval,但这是有风险的,不是一个好的解决方案。
是否有办法在获取和显示列表后立即运行我的JS脚本?
如果可能的话,我不想深入了解Wordpress代码,而是在那里找到抓取和插入JS。
发布于 2022-09-23 19:10:09
一种方法是在向ul元素中添加任何新的子元素时使用MutationObserver (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)调用您的课程排序函数。
如果ul元素存在于页面加载中,并且它的列表项是异步附加的,那么它是相当无痛的(并且在性能方面也不是很昂贵):
(() => {
const ul = document.querySelector( 'ul.course-list' );
// If we can't find our target ul, bail.
if ( ! ul ) {
return;
}
const sortCourses = () => {
// Add the code you already have for sorting the courses here.
};
if (ul.querySelector("li")) {
sortCourses();
}
const config = { childList: true };
const observer = new MutationObserver(() => {
observer.disconnect();
sortCourses();
observer.observe(ul, config);
});
observer.observe(ul, config);
})();https://codesandbox.io/s/black-waterfall-w2eh19?file=/src/course-sort.js
另一方面,如果ul元素本身也作为异步请求的结果添加到dom中,那么它将更加棘手。
首先要找到与目标ul最近的父级,这是页面加载时存在的。最好是一个包装器,除了课程列表之外,没有其他注入的元素(理论上您可以使用body,但是回调会经常被调用,对站点的性能产生负面影响)。
在本例中,我们将设置两个MutationObservers。一个将等待ul存在(一旦它存在将被终止),另一个将监视ul childList的更改。
(() => {
// Closest parent that exists on page load.
const wrapper = document.querySelector("#my-courses");
// Selector where we will be able to find our target ul once it exists.
const ulSelector = "ul.course-list";
// If wrapper could not be found, bail.
if (!wrapper) return;
/**
* Listen for children being added or removed
*/
const observeUl = () => {
const ul = document.querySelector(ulSelector);
const sortCourses = () => {
// The code you already have for sorting the list-items.
};
const observerConfig = { childList: true };
// Listen for added or removed children of our target ul.
const observer = new MutationObserver(() => {
// Stop listening (since sorting involves removing and adding elements)
observer.disconnect();
// Sort the courses.
sortCourses();
// Start listening again
observer.observe(ul, observerConfig);
});
observer.observe(ul, observerConfig);
return true;
};
/**
* @param {String} selector Selector to look for.
* @param {Function} callback Called once the selector returns a match.
*/
const waitForSelector = (selector, callback) => {
/**
* First check if the selector already exists.
* If it does, call the callback and exit this function.
*/
if (document.querySelector(selector)) {
callback();
return;
}
/**
* In addition to listening to changes to the targets childList,
* We'll watch the childList of the target and it's children recursively.
*/
const config = { childList: true, subtree: true };
const observer = new MutationObserver(() => {
if (wrapper.querySelector(ulSelector)) {
// ul exists! Let's disconnect this observer and call the callback.
observer.disconnect();
callback();
}
});
observer.observe(wrapper, config);
};
// Wait for the ul to exist, and then start observing it.
waitForSelector(ulSelector, observeUl);
})();https://codesandbox.io/s/naughty-saha-tzmxlw?file=/src/course-sort.js
https://stackoverflow.com/questions/73829601
复制相似问题