我正在Chrome中开发一个扩展,我想知道:当一个元素出现时,最好的方法是什么?使用纯javascript,间隔检查,直到一个元素存在,或jQuery有一些简单的方法来做到这一点?
当前回答
如果你想让它在一段时间后停止查看(超时),那么下面的jQuery可以工作。10秒后会暂停。我需要使用这段代码而不是纯JS,因为我需要通过名称选择输入,并且在实现其他一些解决方案时遇到了麻烦。
// Wait for element to exist.
function imageLoaded(el, cb,time) {
if ($(el).length) {
// Element is now loaded.
cb($(el));
var imageInput = $('input[name=product\\[image_location\\]]');
console.log(imageInput);
} else if(time < 10000) {
// Repeat every 500ms.
setTimeout(function() {
time = time+500;
imageLoaded(el, cb, time)
}, 500);
}
};
var time = 500;
imageLoaded('input[name=product\\[image_location\\]]', function(el) {
//do stuff here
},time);
其他回答
更新
下面是一个更新的版本,可以使用承诺。如果达到特定的尝试次数,它也会“停止”。
function _waitForElement(selector, delay = 50, tries = 100) {
const element = document.querySelector(selector);
if (!window[`__${selector}`]) {
window[`__${selector}`] = 0;
window[`__${selector}__delay`] = delay;
window[`__${selector}__tries`] = tries;
}
function _search() {
return new Promise((resolve) => {
window[`__${selector}`]++;
setTimeout(resolve, window[`__${selector}__delay`]);
});
}
if (element === null) {
if (window[`__${selector}`] >= window[`__${selector}__tries`]) {
window[`__${selector}`] = 0;
return Promise.resolve(null);
}
return _search().then(() => _waitForElement(selector));
} else {
return Promise.resolve(element);
}
}
用法很简单,用await使用它只是确保你在一个 异步功能:
const start = (async () => {
const $el = await _waitForElement(`.my-selector`);
console.log($el);
})();
过时的版本
只需添加所需的选择器。一旦找到元素,就可以在回调函数中访问它。
const waitUntilElementExists = (selector, callback) => {
const el = document.querySelector(selector);
if (el){
return callback(el);
}
setTimeout(() => waitUntilElementExists(selector, callback), 500);
}
waitUntilElementExists('.wait-for-me', (el) => console.log(el));
我认为仍然没有任何答案在这里与简单易读的工作实例。使用MutationObserver接口来检测DOM的变化,如下所示:
var observer = new MutationObserver(function(mutations) { if ($("p").length) { console.log("Exist, lets do something"); observer.disconnect(); //We can disconnect observer once the element exist if we dont want observe more changes in the DOM } }); // Start observing observer.observe(document.body, { //document.body is node target to observe childList: true, //This is a must have for the observer with subtree subtree: true //Set to true if changes must also be observed in descendants. }); $(document).ready(function() { $("button").on("click", function() { $("p").remove(); setTimeout(function() { $("#newContent").append("<p>New element</p>"); }, 2000); }); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button>New content</button> <div id="newContent"></div>
注意:关于MutationObserver的西班牙语Mozilla文档更多 详情,如果你想了解更多信息。
如果你想让它在一段时间后停止查看(超时),那么下面的jQuery可以工作。10秒后会暂停。我需要使用这段代码而不是纯JS,因为我需要通过名称选择输入,并且在实现其他一些解决方案时遇到了麻烦。
// Wait for element to exist.
function imageLoaded(el, cb,time) {
if ($(el).length) {
// Element is now loaded.
cb($(el));
var imageInput = $('input[name=product\\[image_location\\]]');
console.log(imageInput);
} else if(time < 10000) {
// Repeat every 500ms.
setTimeout(function() {
time = time+500;
imageLoaded(el, cb, time)
}, 500);
}
};
var time = 500;
imageLoaded('input[name=product\\[image_location\\]]', function(el) {
//do stuff here
},time);
如果可以的话,我会尽量避开突变观察者,所以我想到了这个。它看起来类似于上面的一些其他答案。该函数将查找给定DOM调用中存在的第一个元素——className是预期的用法,但它也可以接受tagName或Id。如果您正在寻找具有给定类名或标记名的元素数量,则还可以为精确索引添加参数。
async function waitUntilElementExits(domkey,domquery,maxtime){
const delay = (ms) => new Promise(res => setTimeout(res, ms));
for(let i=0; i<maxtime; i=i+200){
await delay(200);
let elm = document[domkey](domquery);
if( (domkey == 'getElementById' && elm) || elm?.[0] ) break;
}
}
// usage
await waitUntilElementExits('getElementByClassName','some_class_name',10000)
这是一个纯Javascript函数,它允许你等待任何事情。设置更长的间隔,以占用更少的CPU资源。
/**
* @brief Wait for something to be ready before triggering a timeout
* @param {callback} isready Function which returns true when the thing we're waiting for has happened
* @param {callback} success Function to call when the thing is ready
* @param {callback} error Function to call if we time out before the event becomes ready
* @param {int} count Number of times to retry the timeout (default 300 or 6s)
* @param {int} interval Number of milliseconds to wait between attempts (default 20ms)
*/
function waitUntil(isready, success, error, count, interval){
if (count === undefined) {
count = 300;
}
if (interval === undefined) {
interval = 20;
}
if (isready()) {
success();
return;
}
// The call back isn't ready. We need to wait for it
setTimeout(function(){
if (!count) {
// We have run out of retries
if (error !== undefined) {
error();
}
} else {
// Try again
waitUntil(isready, success, error, count -1, interval);
}
}, interval);
}
要调用它,例如在jQuery中,使用如下代码:
waitUntil(function(){
return $('#myelement').length > 0;
}, function(){
alert("myelement now exists");
}, function(){
alert("I'm bored. I give up.");
});
推荐文章
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?
- JavaScript DOM删除元素
- 将dd-mm-yyyy字符串转换为日期
- Javascript复选框onChange
- Javascript函数前导bang !语法
- 如何在页面上遍历所有DOM元素?
- 使用jQuery滚动到一个div
- 在JS/jQuery中触发按键/按键/按键事件?