Làm thế nào để đợi cho đến khi một yếu tố tồn tại?


236

Tôi đang làm việc trên một Tiện ích mở rộng trong Chrome và tôi tự hỏi: cách tốt nhất để tìm ra khi một yếu tố tồn tại là gì? Sử dụng javascript đơn giản, với một khoảng thời gian kiểm tra cho đến khi một phần tử tồn tại hoặc jQuery có một số cách dễ dàng để làm điều này?


1
Có vẻ như mọi tùy chọn duy nhất ở đây ngày hôm nay (bao gồm từ các bình luận) đều lỗi thời hoặc không đầy đủ. Họ không xem xét đầy đủ đầu vào tuyệt vời của @ hughsk, đối số tương thích. Trong khi đó, tôi khuyên bạn chỉ nên sử dụng bản cập nhật của Brandon cho câu trả lời của Ryan để đơn giản hơn và ít rủi ro hơn về chi phí, tôi cho rằng.
cregox

4
MutationObserver> DOM Mutation Events> setTimeout.
mattsven

2
Không phải từ nơi tôi đứng. setTimeouttương thích, đơn giản để thực hiện, đơn giản để duy trì và có chi phí không đáng kể.
cregox

setTimeout+ jQueryít hơn lý tưởng theo ý kiến ​​của tôi vì hai lý do: 1.) jQuery bloat 2.) bạn không cần truy vấn thủ công DOM cho các phần tử, các sự kiện đánh bại tốc độ đó một cách dễ dàng, 3.) nó sẽ luôn chậm hơn bất kỳ bản địa nào thực hiện. Nếu bạn cần làm bất cứ điều gì dựa trên sự hiện diện của một yếu tố một cách hợp lý nhanh chóng, đặc biệt nếu trải nghiệm người dùng liền mạch là mục tiêu của bạn, thì nó kém hơn.
mattsven

3
Có 3 loại người: những người có thể đếm và những người không thể. ; P
cregox

Câu trả lời:


148

DOMNodeInsertedđang bị phản đối, cùng với các sự kiện đột biến DOM khác, vì các vấn đề về hiệu suất - cách tiếp cận được đề xuất là sử dụng M mutObserver để xem DOM. Nó chỉ được hỗ trợ trong các trình duyệt mới hơn, vì vậy bạn nên quay lại DOMNodeInsertedkhi MutationObserverkhông có sẵn.

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
Tôi luôn thấy M mutObserver api hơi phức tạp nên tôi đã xây dựng một thư viện, đến.js , để cung cấp một api đơn giản hơn để lắng nghe việc tạo / xóa phần tử.
Uzair Farooq

15
Tôi khuyên bạn nên sử dụng thư viện tuyệt vời @UzairFarooq github.com/uzairfarooq/arrive
Dennis

3
Hai điều cần lưu ý: (1) Nó sẽ là tốt hơn để làm if (mutation.addedNodes.length)kể từ khi if (mutation.addedNodes)vẫn sẽ trở lại đúng ngay cả khi nó là một mảng trống. (2) Bạn không thể làm được mutation.addedNodes.forEach()vì thêmNodes là một nútList và bạn không thể lặp qua một nútList với forEach. Để biết giải pháp cho vấn đề này, hãy xem babmotto.com/ditch-the-array-foreach-call-nodelist-hack
thdoan

3
Bạn có thể cho một ví dụ về cách người ta sẽ sử dụng điều này? Không chắc chắn nơi để đặt bộ chọn jquery hoặc mã tôi muốn thực thi khi phần tử DOM tồn tại.
Siêu anh hùng

1
@Superdooperhero Tôi đã trả lời với ví dụ dễ hiểu. Kiểm tra nó. stackoverflow.com/a/57395241/6542186
SilverSurfer

113

Tôi đã gặp vấn đề tương tự, vì vậy tôi đã tiếp tục và viết một plugin cho nó.

$(selector).waitUntilExists(function);

Mã số:

;(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
Cảm ơn bạn cho các plugin. Tôi rẽ nhánh và cải thiện nó một chút. Hãy thoải mái lấy bất cứ thứ gì bạn muốn từ bản cập nhật của tôi. Tôi có một vài cải tiến được lên kế hoạch, vẫn: plugin cập nhật
Brandon Belvin

8
sẽ rất tuyệt nếu không có jquery dep quá ...;)
knutole

4
có lẽ bạn nên đề cập đến cách nó hoạt động: nó hoạt động bằng cách hỏi cứ sau 500 ms nếu phần tử tồn tại (sử dụng a window.setInterval). Tôi không biết MutationObservercâu trả lời có hoạt động hay không bằng cách bỏ phiếu ...
thể thao

2
Nó không hoạt động đúng nếu phần tử đã có trên trang. Đây là phiên bản phù hợp của chức năng này: gist.github.com/PizzaBrandon/5709010
Roland Soós

2
Bạn có thể giải thích việc sử dụng ;vào đầu hàm ( ;(function ($, window) {) là gì không?
mrid

76

Đây là một hàm JavaScript cốt lõi để chờ hiển thị một phần tử.

Thông số:

  1. selector: Hàm này tìm phần tử $ {selector}
  2. time: Hàm này kiểm tra xem phần tử này có tồn tại sau mỗi $ {time} mili giây không.

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

Ví dụ: cài đặt selector="#div1"time=5000sẽ tìm kiếm thẻ HTML có id="div1"5000 mili giây.


Đẹp! Bạn có thể viết điều này để bất kỳ bộ chọn có thể được chấp nhận?
mattsven

Tôi nghi ngờ tôi có thể làm điều đó .. Nhưng làm ơn hãy xem bài đăng này để nhận
getEuityByXpath


1
Bạn có thể viết nó để sử dụng quan sát đột biến thay thế?
SuperUberDuper

hoặc bạn có thể viết lại cái này để sử dụng một lời hứa?
SuperUberDuper

25

Bạn có thể nghe DOMNodeInsertedhoặcDOMSubtreeModified các sự kiện kích hoạt bất cứ khi nào một phần tử mới được thêm vào DOM.

Ngoài ra còn có plugin LiveQuery jQuery sẽ phát hiện khi một phần tử mới được tạo:

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

1
Plugin rất đẹp! Có bất kỳ chức năng như thế trong jquery trực tiếp? Tôi tự hỏi rằng không có tính năng hiện có để làm điều đó. Và nếu đây là plugin, vui lòng bỏ phiếu cho câu trả lời này;) Đối với tôi, nó hoạt động hoàn hảo. Cảm ơn rât nhiều.
Samuel

1
Lưu ý IE 9 triển khai DOMNodeInserted nhưng có một lỗi lớn khi nó không kích hoạt khi bạn thêm một phần tử vào thời gian này, đó là phần lớn thời gian bạn muốn sử dụng nó. Chi tiết có tại: help.dottoro.com/ljmcxjla.php
mikemaccana

23

Tôi đã sử dụng phương pháp này để chờ một phần tử xuất hiện để tôi có thể thực hiện các chức năng khác sau đó.

Giả sử doTheRestOfTheStuff(parameters)chức năng chỉ nên được gọi sau khi phần tử có ID the_Element_IDxuất hiện hoặc tải xong, chúng ta có thể sử dụng,

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

21

Bạn có thể làm

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

});

Xin lưu ý rằng điều này sẽ chỉ hoạt động nếu phần tử có trong DOM khi được yêu cầu từ máy chủ. Nếu phần tử đang được thêm động thông qua JavaScript, nó sẽ không hoạt động và bạn có thể cần xem các câu trả lời khác.


7
Các .ready()chức năng hoạt động cho hầu hết bất cứ điều gì (nếu không muốn nói bất cứ điều gì), không chỉ document. Nó chỉ không hoạt động với các yếu tố được tạo động, ngay cả trên .live().
Richard Neil Ilagan

7
@Bery, như Richard đã chỉ ra, điều này chỉ hoạt động đối với các yếu tố đã có trong HTML khi được yêu cầu lần đầu tiên từ máy chủ. Nếu Javascript được sử dụng để thêm một phần tử động vào DOM, thì nó không hoạt động.
Chandranshu

6
@Sam, bạn có thể vui lòng làm rõ cách gắn nó vào tham chiếu của phần tử trong bộ nhớ không?
Vikas Singhal

3
Câu trả lời này không chính xác. Những gì bạn thực sự kiểm tra ở đây là thường xuyên $(document).ready(), không phải là yếu tố bạn nghĩ nó cũng sẽ áp dụng. Đó chỉ là cách người nghe đặc biệt này làm việc. Ví dụ
Shikkediel

1
Việc sử dụng này không được khuyến nghị theo api.jquery.com/ yet
splintor

14

Tôi nghĩ rằng vẫn không có bất kỳ câu trả lời nào ở đây với ví dụ làm việc dễ đọc và dễ đọc. Sử dụng M mutObserver interface để phát hiện các thay đổi DOM, như thế này:

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>

Lưu ý: Tài liệu Mozilla của Tây Ban NhaMutationObserver sẽ chi tiết hơn nếu bạn muốn biết thêm thông tin.


2
Xem xét để lại một bình luận giải thích lý do của downvote, vì vậy tôi có thể cải thiện câu trả lời của tôi. Cảm ơn.
SilverSurfer

12

Đơn giản chỉ cần thêm bộ chọn bạn muốn. Khi yếu tố được tìm thấy, bạn có thể có quyền truy cập vào chức năng gọi lại.

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
PossessWithin đồng ý, đây là một giải pháp rất sạch sẽ và hiệu quả với tôi.
jstafford

3
Câu trả lời này hoạt động trên IE8-10 cũng như các trình duyệt hiện đại. Vấn đề chính là nó sẽ tiếp tục chạy nếu phần tử không tồn tại - vì vậy tốt nhất là khi nào bạn chắc chắn phần tử sẽ ở đó. Nếu không, bạn có thể thêm một bộ đếm.
Cho tên

1
Làm việc hoàn hảo với tôi
James Stewart

1
Làm việc như quyến rũ !!
Aman

1
Chúng giống nhau, không giống nhau. Hơn nữa, nhiều người đang làm như vậy. Cuối cùng, tôi tự mã hóa giải pháp này. Đó là một lý do kém, tuy nhiên, ngay cả khi nó thực sự là như vậy, tôi đánh giá cao một bình luận cho tôi biết. Câu trả lời giải quyết vấn đề của OP và không có động cơ rõ ràng nào bị hạ thấp.
Pháo đài Diego

11

Đối với cách tiếp cận đơn giản bằng jQuery, tôi thấy điều này hoạt động tốt:

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

Ở đây chúng tôi chỉ cần kiểm tra cứ sau 500ms để xem phần tử có được tải hay không, khi có, chúng tôi có thể sử dụng nó.

Điều này đặc biệt hữu ích để thêm trình xử lý nhấp chuột vào các yếu tố đã được thêm động vào tài liệu.


8

Làm thế nào về chèn thư viện ?

ins insertQuery sử dụng các hàm gọi lại Hoạt hình CSS được đính kèm với (các) bộ chọn được chỉ định để chạy một cuộc gọi lại khi một phần tử được tạo. Phương pháp này cho phép các cuộc gọi lại được chạy bất cứ khi nào một phần tử được tạo, không chỉ lần đầu tiên.

Từ github:

Cách không sự kiện để bắt các nút hiển thị. Và nó sử dụng bộ chọn.

Nó không chỉ hỗ trợ trình duyệt rộng hơn, nó có thể tốt hơn DOMMutingObserver cho một số thứ nhất định.

Tại sao?

  • Vì các sự kiện DOM làm chậm trình duyệt và chèn vào không
  • Bởi vì Trình quan sát đột biến DOM có ít hỗ trợ trình duyệt hơn so với insQueryQuery
  • Bởi vì với insertQuery, bạn có thể lọc các thay đổi DOM bằng cách sử dụng các bộ chọn mà không cần chi phí hiệu năng!

Hỗ trợ rộng rãi!

IE10 + và hầu hết mọi thứ khác (bao gồm cả điện thoại di động)


7

Đây là một chức năng hoạt động như một trình bao bọc mỏng xung quanh MutingObserver. Yêu cầu duy nhất là trình duyệt hỗ trợ MutingObserver; không có sự phụ thuộc vào JQuery. Chạy đoạn mã dưới đây để xem ví dụ hoạt động.

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

Đây là một giải pháp trả về Promise trong vanilla Javascript (không có cuộc gọi lại lộn xộn). Theo mặc định, nó kiểm tra mỗi 200ms.

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

Đây là một chức năng Javascript thuần túy cho phép bạn chờ đợi mọi thứ. Đặt khoảng thời gian dài hơn để lấy ít tài nguyên CPU hơ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);
}

Để gọi điều này, ví dụ như trong jQuery, hãy sử dụng một cái gì đó như:

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

3

Một giải pháp trả lại một Promise và cho phép sử dụng thời gian chờ (tương thích IE 11+).

Đối với một yếu tố duy nhất (loại Element):

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

Đối với nhiều phần tử (loại NodeList):

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

Ví dụ:

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

Hoạt động cho cả danh sách các yếu tố và một yếu tố duy nhất.


1
Giải pháp yêu thích của tôi! Tại sao phải kiểm tra element instanceof HTMLElement? Nó có thể là bất cứ điều gì khác hơn nullhay HTMLElementkhông?
Leeroy

1
Bạn nêu lên một điểm thú vị. Tôi nên làm cho nó rộng hơn bằng cách sử dụng Elementthay thế (cố định). Tôi chỉ thực hiện kiểm tra vì tôi muốn chắc chắn biến đó elementcó thuộc tính innerHTMLnhư trạng thái tài liệu MDN Element . Hãy loại bỏ nó nếu bạn không quan tâm đến nó!
Anwar

2

Một ví dụ rõ ràng hơn bằng cách sử dụng MutingObserver:

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

2

Đây là một giải pháp đơn giản cho những người đã quen với lời hứa và không muốn sử dụng bất kỳ lib hoặc bộ hẹn giờ của bên thứ ba nào.

Tôi đã sử dụng nó trong các dự án của tôi trong một thời gian

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

Để dùng nó:

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

hoặc với async / đang chờ

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

Đây là gọn gàng! Phần thú vị về nó là bạn có thể sử dụng nó với async/ awaitquá. Bạn cũng có thể có thể đạt được hiệu suất cao hơn bằng cách thực hiệnmutations.addedNodes.find(node => node.matchesSelector("..."))
mattsven

@mattsven Điểm tốt! Chỉ kiểm tra các nút trong các đột biến có hiệu suất cao hơn so với thực hiện document.querySelector.
Yong Wang

Vui lòng sửa lỗi chính tả, watiForElm để chờForElm
dalvir

1

Nếu bạn muốn nó ngừng tìm kiếm sau một thời gian (hết thời gian) thì jQuery sau sẽ hoạt động. Nó sẽ hết thời gian sau 10 giây. Tôi cần sử dụng mã này thay vì JS thuần vì tôi cần chọn đầu vào qua tên và gặp khó khăn khi triển khai một số giải pháp khác.

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

Tôi thường sử dụng đoạn mã này cho Trình quản lý thẻ:

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

0

nếu bạn có các thay đổi dom async, chức năng này sẽ kiểm tra (với giới hạn thời gian tính bằng giây) cho các thành phần DOM, nó sẽ không nặng đối với DOM và dựa trên Promise :)

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 });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.