Good day everybody,
I'm trying to get an element by its ID in javascript and it returns me null.
Actually this element isn't fully load when the DOM is because of the plugin Restrict Content Pro (where the targeted element is from) making request after page is loaded (see the ref. image below).
The temporary solution I wrote is basically a 2 sec setTimeOut on the getElementByID function which is kind of ... brutal. ☺
If the plugin takes more than 2 sec to load, it won't work.
So, my question is : do you know any way to properly do so?
Something like
- while returns null
try to get it
- when returns element
stop the loop
good to know : document.onload or window.onlaod won't work since the plugin loads element after the page is fully display.
Thanks in advance!
my solution:
do {
var getId = getElementByID();
if(getID!=null){
// to do
}
}
while (getId==null);
Related
I'm trying to use Javascript to retrieve elements from an HTML widget on the page. I can't just use the usual document.getelementsbyclassname etc. as the widget is treated as an embedded section of the page.
I have tried this:
var iframe = document.getElementsByClassName("widgetclassname")[0];
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
I've used that in the past for iframes but not for this. I'm getting this error:
Uncaught TypeError: Cannot read property 'contentDocument' of undefined
I've tried adding a delay and moving around items in case it's a timing thing (trying to get things before it's loaded properly) but it made no difference.
I can't use ID instead of classname as the widget doesn't have one and I can't change that.
Cannot read property 'contentDocument' of undefined means "Hey! iframe is undefined!" Which means that your getElementsByClassName() is returning an empty node list.
We cannot help you further without a way of looking at the document you are trying to query. Are you using the developer tools to ensure that the <iframe> you want has that class on it? Exactly, no typos, no case changes?
Alternatively, you can try using:
// first iframe in the document
var iframe = document.querySelector('iframe');
// third iframe in the document
var iframe = document.querySelectorAll('iframe')[2];
Edit: in response to our chat discussion, the problem is that the page is dynamically loading content, and the script you are trying to run is taking place before that content has been loaded.
A simple hack is to wait for the element you want to load and then run the code you want. For example:
document.title = "Search Results - AvenaGo";
var waitForHotel = setInterval(function(){
var hotelName = document.querySelector('.hotel_page-hotel_name');
if (hotelName) {
clearInterval(waitForHotel);
document.title = hotelName.textContent + ' - AvenaGo';
}
}, 100);
Every 100ms this code will run and check to see if an element with the class hotel_page-hotel_name has loaded yet. If it has, it will stop checking, and modify the title of the page based on the text in that element.
I am testing a webpage that has multiple forms in it.
When I use
client.frame({id:client.element('#frameId')});
I don't get any error, but when I try to interact with an element within that frame I get a RuntimeError telling me the element could not be located.
I have been looking out for literature about how the frame() method works but I don't have any luck.
I was also using webdriver.io and it looks like documentation is a bit wrong.
You can access frames:
1) via it's number on the page. For example the first frame met in HTML DOM is
client.frame(0), second client.frame(1) etc
2) via name attribute:
<frame name="test"></frame>
client.frame('test')
3) find the element with client.element('css_selector'), then in a callback pass the returned value to the .frame()
The way to go to a new frame is:
client.frame(<id of frame here>)
What you have should work too though. Try doing a client.waitForExist on an element that only exists on the frame, instead of just switching to frame and immediately trying to interact with element in that frame, as you may be firing your interaction event before selenium has had a chance to fully switch to the frame:
client.frame(<id of frame here>
client.waitForExist(<id of some css element that only exists in the frame>)
client.frame(<name_of_frame>) worked.
I tried using a selector like #idOfSelector but it didn't seem to work.
This works for me
const frameValue = browser.element('frame_selector').value;
browser.frame(frameValue);
Hopefully, it works for you.
I want to have a page turn effect like the one seen on this page: jFlip demo except I want to automate the page turning, like make it happen every second, 20 times (or however many images I have). I want to be able to trigger this animation to run either on page load, when a button is clicked, etc.
Unfortunately I don't understand jQuery all that well and the plugin's events seem rather complicated to me, probably mostly due to my inexperience with jQuery. Any help on which direction I should go, methods I should try? I am not limiting myself to jQuery or even Javascript, this is just the example I have found that achieves my desired effect.
You can find the updated code here. replace this with old one.
Usage :
var jFlip = new Flip("#g1",300,300,{background:"green",cornersTop:true,scale:"fit"});
// here #g1 is a jquery selector (make sure it returns only one).
// The structure is Flip(JQselector,width,height,options)
then use the jFlip object to flip slides/pages
jFlip.flipMe() // for next slide
jFlip.flipMe(true) // for prev slide
for binding a function to slide change event you can use
$("#g1").bind("flip.jflip",function(event,index,total){
$("#l1").html("Image "+(index+1)+" of "+total);
});
// here the selector is same as the one passed inside jFlip function.
Try this and let me know the feedback.
Can't seem to get this one to work...
I have a page that hides certain links. When the DOM is loaded, I'm using jQuery to toggle some of those elements. This is driven by using a data attribute like so:
<div class="d_btn" data-usr='48'>
<div class="hidden_button">
Then, I have the code:
$.each($(".d_btn"), function() {
var btn = $(this).data('usr');
if ( btn == '48' ){
$(this).children('.hidden_button').toggle();
}
The above all works as planned. The problem is that I am trying to remove the data-usr from the class .d_btn once the if statement is evaluated. I've tried the following and nothing works (i.e., after the page is loaded, the source still shows the data-usr attribute:
$(this).removeAttr("data-usr");
$(this).removeData("usr");
I've been working on this for a couple of hours now and...nothing! Help is greatly appreciated!
UPDATE
I've tried the great suggestions of setting the data attribute to an empty string but I'm still not getting the desired result.
To explain a little further, The reason I'm trying to remove the attribute is so when an ajax response adds another item to the page, the previously added items would already have the button either shown or hidden. Upon AJAX response, I'm calling the same function once the DOM is loaded.
Currently, when something is added via AJAX, it toggles all the buttons (showing the ones that were hidden and vice versa.) Ugh...
I'm also fully willing to try alternatives to my approach. Thanks!
UPDATE
Well, the light bulb just flashed and I am able to do what I want to do by just using .show() instead of .toggle()
Anyway, I'd still like to find an answer to this question because the page will be potentially checking hundreds of items whenever something is added - this seems horribly inefficient (even for a computer, hahaha.)
Why don't you set the value to a random value or empty variable instead if removeAttr does not work..
$(this).attr("data-usr" , '');
$(this).prop("data-usr" , '');
Changing the DOM doesn't affect the source. It affects the DOM, which you can view with the Inspector/Developer Tools. Right click => View Source will give you the original source of the page, not the actual current source as modified by JavaScript.
Set it to a blank string:
$(this).attr("data-usr", "");
I second what Kolink said: check the DOM, not the source. (Chrome: Ctrl + Shift + i).
As others have stated. Checking the source will only show the original unedited source for the webpage. What you need to do is check the DOM using developer tools.
I've just checked everything in Chrome's inspector on jsfiddle here and the attribute is definitely being removed as well as the data.
I am trying to run some JQuery script on a particular page but only if a certain page loads.
The Scenario: We have one page that loads (i.e., webpage.aspx) and it loads different content based on the referring click. (i.e., webpage.aspx?contentId=1, webpage.aspx?contentId=2, webpage.aspx?contentId=3, etc). Here is my problem. I need to have a particular part of the page removed if only one specific contentId is pulled. I am trying to do this in JQuery and can't seem to figure it out.
Here's what i have been working with so far. I realize it's not correct but hopefully it gives you a starting point to work with.
Thanks.
CODE:
$(window).load(function() {
var $deleteNewRow = $("div.col.w140 tbody:first").find("td:first").parent().remove();
if($('#dealer-info h1').indexOf('Ferrari') != -1) {
$deleteNewRow
}
});
What you store in your $deleteNewRow variable isn't the jQuery method, that method will already execute. You want to do that method in your if statement, something like this (note that you are also missing the .text() in the if statement):
$(window).load(function() {
if($('#dealer-info h1').text().indexOf('Ferrari') != -1) {
$("div.col.w140 tbody:first").find("td:first").parent().remove();
}
});
You can use jQuery :contains selector to check for the existence. Here is the docs.
Then to delete find the element and then use remove.
$("div.col.w140 tbody:first").find("td:first").parent().remove();