How to wait until an element exists?
DOMNodeInserted
is being deprecated, along with the other DOM mutation events, because of performance issues - the recommended approach is to use a MutationObserver to watch the DOM. It's only supported in newer browsers though, so you should fall back onto DOMNodeInserted
when MutationObserver
isn't available.
let observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (!mutation.addedNodes) return
for (let i = 0; i < mutation.addedNodes.length; i++) {
// do things to your newly added nodes here
let node = mutation.addedNodes[i]
}
})
})
observer.observe(document.body, {
childList: true
, subtree: true
, attributes: false
, characterData: false
})
// stop watching using:
observer.disconnect()
Javascript: How to wait until an element exists in DOM
I am on a phone and can't check your code, but based on the details you gave, you need to capture the input bubble (since it's not possible to target a dynamically created button directly)
To do so, put your event handler on an element that already exists without user input, such as an upper div... when the user clicks the button the event will bubble up to that div and you can capture it there.
You said you're new to Javascript, so if you're unfamiliar with the concept Google search for "Javascript event bubbling" and there are plenty of great articles.
EDIT: I created a very basic example of this in action if you want to see, just save this as an HTML file and open in your browser.
<html>
<body>
<div>
<button id="addBtn">Add New Button</button>
</div>
<div id="newBtnContainer"></div>
</body>
</html>
document.getElementById('addBtn').onclick = function() {
var btn = document.createElement('button');
var btnText = document.createTextNode("Dynamically Created Button");
btn.appendChild(btnText);
document.getElementById('newBtnContainer').appendChild(btn);
}
document.getElementById('newBtnContainer').onclick = function() {
alert('Found the button!');
}
Hope this helps your use case
Thanks
Javascript wait until element loaded on website using chrome extensiion
Can be done with MutationObserver:
function handleSomeDiv(someDiv) {
console.log("div was handled");
}
const observer = new MutationObserver(function (mutations, mutationInstance) {
const someDiv = document.getElementById('some-div');
if (someDiv) {
handleSomeDiv(someDiv);
mutationInstance.disconnect();
}
});
observer.observe(document, {
childList: true,
subtree: true
});
How to wait until an element exists with JavaScript?
I finally made it with MutationObserverinterface
in an easy way instead of with promises
.
var handler = { makeThings: 0, otherStuff: 0};var globalHandler = new Proxy(handler, { set: function(obj, prop, value) { obj[prop] = value if (prop == "makeThings") { var observer = new MutationObserver(function(mutations) { if ($("p").length) { console.log("Exist, lets do something"); observer.disconnect(); } }); // start observing observer.observe(document.body, { childList: true, subtree: true }); } return true; }});
$(document).ready(function() { $("button").on("click", function() { $("p").remove(); globalHandler.makeThings = 1; //This element comes with ajax but I use a setTimeout for this example setTimeout(function() { $("#newContent").append("<p>Ajax element</p>"); }, 2000); });});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><body> <button>New content</button> <div id="newContent"></div></body>
How to wait until an element is present in Selenium?
You need to call ignoring
with exception to ignore while the WebDriver
will wait.
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(200, TimeUnit.MILLISECONDS)
.ignoring(NoSuchElementException.class);
See the documentation of FluentWait for more info. But beware that this condition is already implemented in ExpectedConditions so you should use
WebElement element = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
*Update for newer versions of Selenium:
withTimeout(long, TimeUnit) has become withTimeout(Duration)
pollingEvery(long, TimeUnit) has become pollingEvery(Duration)
So the code will look as such:
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30)
.pollingEvery(Duration.ofMillis(200)
.ignoring(NoSuchElementException.class);
Basic tutorial for waiting can be found here.
Wait until element exists, loop, then store in variable
As you are performing an asyncrhonous task, I'd suggest modifying your code to accept a callback, or return a promise. Here is a callback modification:
var i =1;
function waitForElClass(data, cb){
var element = data.selected;
var index = data.index;
var findEl = document.getElementsByClassName(element)[index];
console.log(i);
i++;
var to = window.setInterval(function(){
if($(findEl).length){
console.log(findEl);
cb(findEl);
window.clearInterval(to);
}
},500)
}
It could then be used as follows:
var data = {selected: 'new', index: 0};
var element;
waitForElClass(data, function(el) {
element = el;
//or something more meaningful here
});
Selenium wait until element by ID is present or visible
You can use this.
Java:
WebDriverWait w1 = new WebDriverWait(driver, 5);
w1.until(ExpectedConditions.visibilityOfElementLocated(By.id("submit_btn")));
Python:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
See more on: https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html
Related Topics
Pull Variable Value from JavaScript Source Using Beautifulsoup4 Python
Why the Value of Input Elements Are Not Changing
Is There Any Workaround (Or Hack) to Make the Audio Autoplay on Chrome, Firefox and Safari
Want to Hide Menu by Clicking Outside the Menu Element
Navigationduplicated Navigating to Current Location ("/Search") Is Not Allowed
Focus Next Input Once Reaching Maxlength Value
How to Create a Horizontal Scrolling Chart.Js Line Chart With a Locked Y Axis
Blob Createobjecturl Download Not Working in Firefox (But Works When Debugging)
How to Parse Through Local Json File in React Js
How to Toggle Class to a Div Element in Reactjs
React Use State to Show Otherwise Hide
Why New Date().Toisostring() Is Loosing Timezone
Remove Specific Characters from String Jquery
How to Get Pasted Value from Reactjs Onpaste Event
Extracting Key:Value Pairs Assoc With Regex from String on JavaScript
How to Place Button on Right Side in Reactjs
Form Builder - Cannot Read Property 'Get' of Undefined, Issue With Validators