Bir eleman var olana kadar nasıl beklenir?


237

Chrome'da bir Uzantı üzerinde çalışıyorum ve merak ediyorum: bir öğe ortaya çıktığında öğrenmenin en iyi yolu nedir? Bir öğe var olana kadar kontrol eden bir aralıkla düz javascript kullanmak mı, yoksa jQuery'nin bunu yapmanın kolay bir yolu var mı?


1
Bugün buradaki her seçeneğin (yorumlar dahil) ya eski ya da eksik olduğu anlaşılıyor. @ Hughsk'un müthiş girdisini, uyumluluk argümanını tam olarak düşünmüyorlar. Bu arada, Brandon'ın genel sadelik ve daha az genel risk için verdiği cevap üzerindeki güncellemesini kullanmanızı öneririm.
cregox

4
MutationObserver> DOM Mutation Events> setTimeout.
mattsven

2
Durduğum yerden değil. setTimeoutuyumludur, uygulaması kolaydır, bakımı kolaydır ve ihmal edilebilir ek yüke sahiptir.
cregox

setTimeout+ jQuerybence iki nedenden ötürü idealden daha az: 1.) jQuery bloat 2.) gereksiz yere DOM için öğeleri sorgulamak, olaylar bu hızlı-bilge kolayca yendi, 3.) her zaman herhangi bir yerli daha yavaş olacaktır uygulanması. Bir öğenin varlığına dayalı olarak herhangi bir şey yapmanız gerekiyorsa, özellikle de sorunsuz kullanıcı deneyimi hedefinizse, daha düşüktür.
mattsven

3
3 çeşit insan vardır: sayanlar ve sayanlar. ; P
cregox

Yanıtlar:


149

DOMNodeInsertedperformans sorunları nedeniyle diğer DOM mutasyon olaylarıyla birlikte kullanımdan kaldırılıyor - önerilen yaklaşım, DOM'u izlemek için bir MutationObserver kullanmaktır . Eğer üzerine geri düşmek gerekir böylece sadece olsa yeni tarayıcılarda desteklenen DOMNodeInsertedzaman MutationObserverkullanılamaz.

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (!mutation.addedNodes) return

    for (var i = 0; i < mutation.addedNodes.length; i++) {
      // do things to your newly added nodes here
      var node = mutation.addedNodes[i]
    }
  })
})

observer.observe(document.body, {
    childList: true
  , subtree: true
  , attributes: false
  , characterData: false
})

// stop watching using:
observer.disconnect()

50
Ben her zaman MutationObserver api biraz karmaşık buldum, bu yüzden eleman oluşturma / kaldırma dinlemek için daha basit bir api sağlamak için arri.js , bir kütüphane inşa ettik .
Uzair Farooq

15
@UzairFarooq mükemmel kütüphanesini kullanmanızı tavsiye ederim github.com/uzairfarooq/arrive
Dennis

3
Nota iki şey: (1) Bunu yapmak daha iyi olurdu if (mutation.addedNodes.length)çünkü if (mutation.addedNodes)boş bir dizi olsa bile hala doğru dönecekti. (2) mutation.addedNodes.forEach()addNodes bir nodeList olduğu ve forEach ile bir nodeList üzerinden yineleyemediğiniz için yapamazsınız. Buna bir çözüm için bkz. Toddmotto.com/ditch-the-array-foreach-call-nodelist-hack
thdoan

3
Bunu nasıl kullanacağınıza dair bir örnek verebilir misiniz? DOM öğesi varken yürütmek istediğim jquery seçiciyi veya kodu nereye koyacağımdan emin değilim.
Superdooperhero

1
@Superdooperhero Kolay örnekle bir cevap verdim. Kontrol et. stackoverflow.com/a/57395241/6542186
SilverSurfer

113

Aynı sorunu yaşıyordum, bu yüzden devam ettim ve bunun için bir eklenti yazdım .

$(selector).waitUntilExists(function);

Kod:

;(function ($, window) {

var intervals = {};
var removeListener = function(selector) {

    if (intervals[selector]) {

        window.clearInterval(intervals[selector]);
        intervals[selector] = null;
    }
};
var found = 'waitUntilExists.found';

/**
 * @function
 * @property {object} jQuery plugin which runs handler function once specified
 *           element is inserted into the DOM
 * @param {function|string} handler 
 *            A function to execute at the time when the element is inserted or 
 *            string "remove" to remove the listener from the given selector
 * @param {bool} shouldRunHandlerOnce 
 *            Optional: if true, handler is unbound after its first invocation
 * @example jQuery(selector).waitUntilExists(function);
 */

$.fn.waitUntilExists = function(handler, shouldRunHandlerOnce, isChild) {

    var selector = this.selector;
    var $this = $(selector);
    var $elements = $this.not(function() { return $(this).data(found); });

    if (handler === 'remove') {

        // Hijack and remove interval immediately if the code requests
        removeListener(selector);
    }
    else {

        // Run the handler on all found elements and mark as found
        $elements.each(handler).data(found, true);

        if (shouldRunHandlerOnce && $this.length) {

            // Element was found, implying the handler already ran for all 
            // matched elements
            removeListener(selector);
        }
        else if (!isChild) {

            // If this is a recurring search or if the target has not yet been 
            // found, create an interval to continue searching for the target
            intervals[selector] = window.setInterval(function () {

                $this.waitUntilExists(handler, shouldRunHandlerOnce, true);
            }, 500);
        }
    }

    return $this;
};

}(jQuery, window));

5
Eklenti için teşekkürler. Çatalladım ve biraz geliştirdim. Güncellememden istediğinizi almaktan çekinmeyin. Planlanan birkaç iyileştirmem daha var: güncellenmiş eklenti
Brandon Belvin

8
jquery dep olmadan da iyi olurdu ...;)
knutole

4
belki nasıl çalıştığından bahsetmelisiniz: her 500 ms'de bir eleman olup olmadığını sorarak çalışır (a window.setInterval). MutationObserverCevabın oylamada da işe yarayıp yaramadığını bilmiyorum ...
spor

2
Öğe zaten sayfadaysa düzgün çalışmaz. İşte bu işlevin uygun sürümü: gist.github.com/PizzaBrandon/5709010
Roland Soós

2
;( ;(function ($, window) {) İşlevinin başlangıcında ne işe yaradığını açıklayabilir misiniz ?
mrid

76

Burada, bir öğenin görüntülenmesini bekleyecek temel bir JavaScript işlevi bulunmaktadır.

Parametreler:

  1. selector: Bu işlev $ {selector} öğesini arar
  2. time: Bu işlev, bu öğenin her {{time} milisaniyede bir var olup olmadığını kontrol eder.

    function waitForElementToDisplay(selector, time) {
            if(document.querySelector(selector)!=null) {
                alert("The element is displayed, you can put your code instead of this alert.")
                return;
            }
            else {
                setTimeout(function() {
                    waitForElementToDisplay(selector, time);
                }, time);
            }
        }

Bir örnek olarak, ayar selector="#div1"ve time=5000kimin HTML etiketine arayacaktır id="div1"her 5000 milisaniye.


Güzel! Herhangi bir seçicinin kabul edilebilmesi için bunu yazabilir misiniz?
mattsven

Yapabileceğimden şüpheliyim .. Ama getElementByXpath'i almak için lütfen bu gönderiye bir göz atın: stackoverflow.com/questions/10596417/…
Etienne Tonnelier


1
Bunun yerine mutasyon gözlemcisini kullanmak için yazabilir misiniz?
SuperUberDuper

ya da bir söz kullanmak için bunu yeniden yazabilir misiniz?
SuperUberDuper

25

Dinleyebilir DOMNodeInsertedveyaDOMSubtreeModifiedDOM'ye yeni bir öğe eklendiğinde tetiklenen olayları olayları .

Ayrıca, yeni bir öğe oluşturulduğunda algılayacak LiveQuery jQuery eklentisi de vardır :

$("#future_element").livequery(function(){
    //element created
});

1
Çok güzel bir eklenti! Doğrudan jquery'de böyle bir işlev var mı? Bunu yapmak için mevcut bir özellik olmadığını merak ediyorum. Ve eğer bu eklenti ise, lütfen bu cevaba oy verin;) Benim için mükemmel çalışıyor. Çok teşekkür ederim.
Samuel

1
Not IE 9 DOMNodeInserted uygular, ancak zaman için bir öğe eklediğinizde tetiklenmeyeceği büyük bir hata vardır, bu da çoğu zaman kullanmak istediğinizdir. Ayrıntılar için: help.dottoro.com/ljmcxjla.php
mikemaccana

23

Bundan sonra diğer işlevleri yürütebilmem için bir öğenin görünmesini beklemek için bu yaklaşımı kullandım.

Diyelim ki doTheRestOfTheStuff(parameters)fonksiyon sadece kimliğine sahip eleman the_Element_IDgöründükten veya yüklemeyi bitirdikten sonra çağrılmalıdır ,

var existCondition = setInterval(function() {
 if ($('#the_Element_ID').length) {
    console.log("Exists!");
    clearInterval(existCondition);
    doTheRestOfTheStuff(parameters);
 }
}, 100); // check every 100ms

21

Yapabilirsin

$('#yourelement').ready(function() {

});

Bunun yalnızca öğenin sunucudan istendiğinde DOM'da bulunması durumunda işe yarayacağını unutmayın. Öğe JavaScript aracılığıyla dinamik olarak ekleniyorsa, çalışmaz ve diğer yanıtlara bakmanız gerekebilir.


7
.ready()En herhangi bir şey için işlev çalışmaları (değil bir şey varsa), sadece document. Sadece dinamik olarak oluşturulmuş öğelerle çalışmaz .live().
Richard Neil Ilagan

7
@Bery, Richard'ın belirttiği gibi, bu yalnızca sunucudan ilk istendiğinde HTML'de zaten bulunan öğeler için çalışır. JavaScript'e dinamik olarak bir öğe eklemek için Javascript kullanılırsa, çalışmaz.
Chandranshu

6
@Sam, bunu bellekteki öğenin referansına nasıl ekleyeceğinizi açıklayabilir misiniz?
Vikas Singhal

3
Bu cevap yanlış. Aslında burada kontrol ettiğiniz şey $(document).ready(), bunun da geçerli olacağını düşündüğünüz bir öğe değil, normaldir. Bu özel dinleyici böyle çalışır. Örnek
Shikkediel

1

14

Bence burada kolay ve okunabilir çalışma örneği ile herhangi bir cevap yok. DOM değişikliklerini tespit etmek için MutationObserver'ı kullanın interface, örneğin:

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>

Not: İspanyolca Mozilla dokümanları hakkında MutationObserverdaha fazla bilgi istiyorsanız daha ayrıntılı bilgi alabilirsiniz.


2
Cevabımı iyileştirebilmem için aşağı oylamanın nedenini açıklayan bir yorum bırakmayı düşünün. Teşekkürler.
SilverSurfer

12

İstediğiniz seçiciyi eklemeniz yeterlidir. Öğe bulunduğunda, geri arama işlevinde erişime sahip olabilirsiniz.

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));

2
Kabul edersek, bu çok temiz bir çözüm ve benim için çalışıyor.
jstafford

3
Bu yanıt IE8-10 ve modern tarayıcılarda çalışır. Ana sorun, öğe yoksa çalışmaya devam etmesidir - bu yüzden öğenin orada olacağından emin olduğunuzda en iyisi. Aksi takdirde, bir sayaç ekleyebilirsiniz.
, Ad

1
Benim için mükemmel çalıştı
James Stewart

1
Çekicilik gibi çalıştı !!
Aman

1
Benzerlerdi, özdeş değillerdi. Dahası, birçok insan aynı şeyi yapıyor. Son olarak, bu çözümü kendim kodladım. Bu kötü bir mantıktır, ancak gerçekten de olsa, bana bildiren bir yorumu takdir ediyorum. Cevap OP'nin sorununu çözüyor ve göz ardı edilecek belirgin bir güdü yok.
Diego Fortes

11

JQuery kullanarak basit bir yaklaşım için bu iyi çalışır buldum:

  // Wait for element to exist.
  function elementLoaded(el, cb) {
    if ($(el).length) {
      // Element is now loaded.
      cb($(el));
    } else {
      // Repeat every 500ms.
      setTimeout(function() {
        elementLoaded(el, cb)
      }, 500);
    }
  };

  elementLoaded('.element-selector', function(el) {
    // Element is ready to use.
    el.click(function() {
      alert("You just clicked a dynamically inserted element");
    });
  });

Burada, elemanın yüklü olup olmadığını görmek için her 500 ms'de bir kontrol ediyoruz, olduğunda, kullanabiliriz.

Bu, özellikle belgeye dinamik olarak eklenen öğelere tıklama işleyicileri eklemek için kullanışlıdır.


8

İnsertionQuery kütüphanesine ne dersiniz ?

insertionQuery, bir öğe oluşturulduğunda geri arama yapmak için belirtilen seçicilere bağlı CSS Animation geri çağrılarını kullanır. Bu yöntem, yalnızca ilk kez değil, bir öğe oluşturulduğunda geri çağrıların çalıştırılmasını sağlar.

Github'dan:

Görünen düğümleri yakalamak için dom-olay olmayan yol. Ve seçiciler kullanıyor.

Sadece daha geniş tarayıcı desteği için değil, belirli şeyler için DOMMutationObserver'dan daha iyi olabilir.

Neden?

  • DOM Etkinlikleri tarayıcıyı yavaşlattığı ve insertionQuery
  • DOM Mutation Observer, inserttionQuery'den daha az tarayıcı desteğine sahip olduğundan
  • Çünkü insertionQuery ile performans yükü olmayan seçicileri kullanarak DOM değişikliklerini filtreleyebilirsiniz!

Yaygın destek!

IE10 + ve çoğunlukla başka herhangi bir şey (mobil dahil)


7

İşte MutationObserver etrafında ince bir sargı görevi gören bir işlev. Tek gereksinim tarayıcının MutationObserver'ı desteklemesidir; JQuery'ye bağımlılık yoktur. Çalışan bir örnek görmek için aşağıdaki snippet'i çalıştırın.

function waitForMutation(parentNode, isMatchFunc, handlerFunc, observeSubtree, disconnectAfterMatch) {
  var defaultIfUndefined = function(val, defaultVal) {
    return (typeof val === "undefined") ? defaultVal : val;
  };

  observeSubtree = defaultIfUndefined(observeSubtree, false);
  disconnectAfterMatch = defaultIfUndefined(disconnectAfterMatch, false);

  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.addedNodes) {
        for (var i = 0; i < mutation.addedNodes.length; i++) {
          var node = mutation.addedNodes[i];
          if (isMatchFunc(node)) {
            handlerFunc(node);
            if (disconnectAfterMatch) observer.disconnect();
          };
        }
      }
    });
  });

  observer.observe(parentNode, {
    childList: true,
    attributes: false,
    characterData: false,
    subtree: observeSubtree
  });
}

// Example
waitForMutation(
  // parentNode: Root node to observe. If the mutation you're looking for
  // might not occur directly below parentNode, pass 'true' to the
  // observeSubtree parameter.
  document.getElementById("outerContent"),
  // isMatchFunc: Function to identify a match. If it returns true,
  // handlerFunc will run.
  // MutationObserver only fires once per mutation, not once for every node
  // inside the mutation. If the element we're looking for is a child of
  // the newly-added element, we need to use something like
  // node.querySelector() to find it.
  function(node) {
    return node.querySelector(".foo") !== null;
  },
  // handlerFunc: Handler.
  function(node) {
    var elem = document.createElement("div");
    elem.appendChild(document.createTextNode("Added node (" + node.innerText + ")"));
    document.getElementById("log").appendChild(elem);
  },
  // observeSubtree
  true,
  // disconnectAfterMatch: If this is true the hanlerFunc will only run on
  // the first time that isMatchFunc returns true. If it's false, the handler
  // will continue to fire on matches.
  false);

// Set up UI. Using JQuery here for convenience.

$outerContent = $("#outerContent");
$innerContent = $("#innerContent");

$("#addOuter").on("click", function() {
  var newNode = $("<div><span class='foo'>Outer</span></div>");
  $outerContent.append(newNode);
});
$("#addInner").on("click", function() {
  var newNode = $("<div><span class='foo'>Inner</span></div>");
  $innerContent.append(newNode);
});
.content {
  padding: 1em;
  border: solid 1px black;
  overflow-y: auto;
}
#innerContent {
  height: 100px;
}
#outerContent {
  height: 200px;
}
#log {
  font-family: Courier;
  font-size: 10pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Create some mutations</h2>
<div id="main">
  <button id="addOuter">Add outer node</button>
  <button id="addInner">Add inner node</button>
  <div class="content" id="outerContent">
    <div class="content" id="innerContent"></div>
  </div>
</div>
<h2>Log</h2>
<div id="log"></div>


6

İşte vanilya Javascript (dağınık geri arama yok) bir Promise döndüren çözüm. Varsayılan olarak her 200 ms'de bir kontrol eder.

function waitFor(selector) {
    return new Promise(function (res, rej) {
        waitForElementToDisplay(selector, 200);
        function waitForElementToDisplay(selector, time) {
            if (document.querySelector(selector) != null) {
                res(document.querySelector(selector));
            }
            else {
                setTimeout(function () {
                    waitForElementToDisplay(selector, time);
                }, time);
            }
        }
    });
}

5

İşte bir şey beklemenizi sağlayan saf bir Javascript işlevi. Daha az CPU kaynağı almak için aralığı daha uzun ayarlayın.

/**
 * @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);
}

Bunu jQuery'de çağırmak için şöyle bir şey kullanın:

waitUntil(function(){
    return $('#myelement').length > 0;
}, function(){
    alert("myelement now exists");
}, function(){
    alert("I'm bored. I give up.");
});

3

A döndüren Promiseve zaman aşımı kullanımına izin veren bir çözüm (uyumlu IE 11+).

Tek bir öğe için (Öğe yazın):

"use strict";

function waitUntilElementLoaded(selector) {
    var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;

    var start = performance.now();
    var now = 0;

    return new Promise(function (resolve, reject) {
        var interval = setInterval(function () {
            var element = document.querySelector(selector);

            if (element instanceof Element) {
                clearInterval(interval);

                resolve();
            }

            now = performance.now();

            if (now - start >= timeout) {
                reject("Could not find the element " + selector + " within " + timeout + " ms");
            }
        }, 100);
    });
}

Birden çok öğe için (NodeList yazın):

"use strict";

function waitUntilElementsLoaded(selector) {
    var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;

    var start = performance.now();
    var now = 0;

    return new Promise(function (resolve, reject) {
        var interval = setInterval(function () {
            var elements = document.querySelectorAll(selector);

            if (elements instanceof NodeList) {
                clearInterval(interval);

                resolve(elements);
            }

            now = performance.now();

            if (now - start >= timeout) {
                reject("Could not find elements " + selector + " within " + timeout + " ms");
            }
        }, 100);
    });
}

Örnekler:

waitUntilElementLoaded('#message', 800).then(function(element) {
    // element found and available

    element.innerHTML = '...';
}).catch(function() {
    // element not found within 800 milliseconds
});

waitUntilElementsLoaded('.message', 10000).then(function(elements) {
    for(const element of elements) {
        // ....
    }
}).catch(function(error) {
    // elements not found withing 10 seconds
});

Hem öğe listesi hem de tek bir öğe için çalışır.


1
En sevdiğim çözüm! Neden kontrol etmeliyim element instanceof HTMLElement? Hiç nullya da dışında bir şey olabilir HTMLElementmi?
Leeroy

1
İlginç bir noktaya değindin. Bunun Elementyerine (sabit) kullanarak daha geniş yapmalıydım . Emin değişken olmak istiyorum çünkü ben sadece çek yapmak elementözelliğine sahiptir innerHTMLolarak Eleman MDN dokümanları devletler . Eğer umursamıyorsanız kaldırmak için çekinmeyin!
Anwar

2

MutationObserver kullanan daha temiz bir örnek:

new MutationObserver( mutation => {
    if (!mutation.addedNodes) return
    mutation.addedNodes.forEach( node => {
        // do stuff with node
    })
})

2

Bu, söz vermeye alışkın olan ve üçüncü taraf kütüphanelerini veya zamanlayıcılarını kullanmak istemeyenler için basit bir çözümdür.

Bir süredir projelerimde kullanıyorum

function waitForElm(selector) {
    return new Promise(resolve => {
        if (document.querySelector(selector)) {
            return resolve(document.querySelector(selector));
        }

        const observer = new MutationObserver(mutations => {
            if (document.querySelector(selector)) {
                resolve(document.querySelector(selector));
                observer.disconnect();
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
}

Kullanmak için:

waitForElm('.some-class').then(elm => console.log(elm.textContent));

veya zaman uyumsuz / beklemede

const elm = await waitForElm('.some-classs')

Bu temiz! Bu konuda serin kısmı async/ ile kullanabilirsiniz olmasıdır await. Ayrıca yaparak daha fazla performans elde edebilirsinizmutations.addedNodes.find(node => node.matchesSelector("..."))
mattsven

@mattsven İyi bir nokta! Sadece mutasyonlardaki düğümleri kontrol etmek, document.querySelector yapmaktan daha etkilidir.
Yong Wang

Lütfen yazım hatasını düzeltin, watiForElm beklemek içinForElm
dalvir

1

Bir süre sonra (zaman aşımı) bakmayı durdurmak istiyorsanız, aşağıdaki jQuery çalışacaktır. 10 saniye sonra zaman aşımına uğrar. Ben adı ile bir girdi seçmek gerekiyordu ve diğer çözümlerin bazılarını uygulamakta sorun vardı çünkü saf JS yerine bu kodu kullanmak gerekiyordu.

 // 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);

0

Genellikle bu pasajı Etiket Yöneticisi için kullanırım:

<script>
(function exists() {
  if (!document.querySelector('<selector>')) {
    return setTimeout(exists);
  }
  // code when element exists
})();  
</script>

0

zaman uyumsuz dom değişiklikleriniz varsa, bu işlev DOM öğelerini (saniye cinsinden zaman sınırı ile) denetler, DOM ve Promise tabanlı için ağır olmayacaktır :)

function getElement(selector, i = 5) {
  return new Promise(async (resolve, reject) => {
    if(i <= 0) return reject(`${selector} not found`);
    const elements = document.querySelectorAll(selector);
    if(elements.length) return resolve(elements);
    return setTimeout(async () => await getElement(selector, i-1), 1000);
  })
}

// Now call it with your selector

try {
  element = await getElement('.woohoo');
} catch(e) { // catch the e }

//OR

getElement('.woohoo', 5)
.then(element => { // do somthing with the elements })
.catch(e => { // catch the error });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.