Using the Firefox browser console I'm trying to select an element in an i-frame. The i-frame is shown in a modal dialog which opens when I click a link.
This example code below does the following:
Click the first link on page which opens a modal dialog
Show alert
Once I close the alert, the code finds all span elements with class
Code then prints the number of span elements found.
This code works at this link:
https://www.sec.gov/edgar/search/#/q=%2522food%2520and%2520drug%2522
$('.preview-file').eq(1).trigger('click');
alert("close this alert");
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
But, when I take out the alert("close this alert"), the code no longer works. Without the alert the code does not find any span elements and prints 0 to the console.
nonworking code (returns 0):
$('.preview-file').eq(1).trigger('click');
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
Why doesn't this code work without the alert? How can I fix this?
Edit:
I tried a while loop to see if I had to wait for something to load, but it also did not work (never-ending loop).
$('.preview-file').eq(i).trigger('click');
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
while($(all).length < 1){
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
}
The iframe doesn't exist on initial page load
Here's an approach you can play with that uses setInterval() to check for existince of the iframe and items inside the iframe that for me is returning a count of four items found
const timer = setInterval(function(){
const $frme=$('#ipreviewer');
// check if frame exists
if($('#ipreviewer').length){
const $items = $frme.contents().find(".sect-efts-search-match-khjdickkwg");
// check if items found
if($items.length){
// do something with the items
console.log('Found ', $items.length, ' items');
// clear interval timer when found
clearInterval(timer)
}
}else{
console.log('Not found')
}
},100)// 1/10th second intervals
$('.preview-file').eq(1).trigger('click');
Related
I have spend a lot of time think about this and tried different things now. I want to scrape a webpage with multiple pages but the page does not reload on page change. Instead, some container data is changed on each changed page. The most difficult thing to do is know when to click the next page button.
Someone might think that this is pretty easy and I thought the same and started off by doing:
$('.pagn a').each(function() {
console.log(`Loop counter`)
$(this).click()
//Code to scrape the new page
})
Now, the loop runs 13 times but only one page is changed. This is because the pagination itself is inside the container that reloads so all other button presses are basically ignored.
To tackle this I needed some kind of a check that makes sure that the new content has loaded before proceeding but if I try to do something like:
$('.pagn a').each(function() {
console.log(`Loop counter`)
while (someConditionToCheckIfPageLoaded) {
}
$(this).click()
//Code to scrape the new page
})
This would be an infinite loop because JavaScript is single threaded and the code to change the condition never fires.
I also tried this which I now know is incorrect.
The indicator for page being loaded is if the button URL matches the page URL.
$('.pagn a').each(function() {
let visitedURL = [];
if ($(this).attr('data-url')) {
let button = $(this)
buttonURL = "https://www.ebay.com/myb/PurchaseHistory#" + $(this).attr('data-url');
(function wait() {
button.click()
if (buttonURL == location.href && !visitedURL.includes(button.html())) {
console.log(button.html())
button.click()
visitedURL.push(button.html())
console.log(buttonURL);
console.log(location.href);
//Scrape page
} else {
setInterval(wait, 5000);
}
})();
}
})
This also only changes one page.
If someone has been able to scrape webpages with multiple pages with JavaScript please let me know how.
Edit1:
Also, I am not sure why this creates an infinite loop as well:
let glbElements = []
$('.pagn a').each(function() {
glbElements.push($(this))
})
for(let i = 0 ; i<glbElements.length; i++){
console.log(`Loop Counter`)
setTimeout(function(){
console.log(`Inside SetTimeout`)
glbElements[i].click()
glbElements.splice(i,1)
},2000)
}
Lopp Counter *5
Inside SetInterval -- Keeps printing
You can use the setTimeout() function to wait after a user clicks a button.
Like this:
<a href='newpage.html'><button id='click'>Click!</button</a>
$('#click').click(function() {
setTimeout(function() {
// code you want executed after page is loaded
}, 100);
});
File 1 has the following script in it:
$(document).ready(function () {
$("#buttonClass").click(function() {
getValueUsingClass();
});
});
function getValueUsingClass(){
var chkArray = [];
$(".chk:checked").each(function() {
chkArray.push($(this).val());
});
var selected;
selected = chkArray.join(',') ;
localStorage.setItem("imgid",selected);
var varmodal = document.getElementById('myinfomodal');
var span = document.getElementsByClassName('infoclose')[0];
varmodal.style.display = "block";
span.onclick = function() {
varmodal.style.display = "none";
}
}
The above script opens the following div/iframe (also in File 1):
<div id="myinfomodal" class="infomodal">
<div class="infomodal-content">
<button class="infoclose">Close</button>
<iframe id="frameid" src="https://outzeal.com/zp2.php" width="100%" height="500px;" style="border:none;"></iframe>
</div>
</div>
The variable selected is supposed to be transferred through localStorage to a second file. The script in the second file is:
window.onload = function () {
var a = localStorage.getItem("imgid");
document.getElementById("demo").innerHTML = a;
if(a == 0){
document.getElementById("demo").innerHTML = "no image selected";
}
}
Please click on this link (not available anymore) for a demo. After clicking on the image the image opens in a modal div. Selecting the check box and clicking on the "Cart icon" opens the div and the iframe file but does not show the value of the variable selected (probably because the function should run after window.onload happens and that has never happened here). If the second file is opened separately (window.onload happens here) the value is shown. I want the value of selected in the modal div. How can that be done? Thanks.
Your code has nothing wrong, it's just a cache problem: I copied your code on my local, of course using zp2.html instead zp2.php (I don't have a PHP server) and it seems to works pretty good: I've got both "no image selected" and "skiing/001", instead on the remote I don't see anything (I think it's because a previous behaviour of zp2.p.
Try to edit your zp2.php and use anonymous navigation, or disable the cache on your browser.
PS: Anyway if you change the value of the checkbox after push the button, the iframe will show the first value because you're using window.onload on zp2.php... If you need a popup you don't need to use iframe and another server page, neither localweb, you can use a global javascript variable.
I'm trying to display div with content after click on image, but when my page is loaded and I try to click then nothing happens. Interesting that if my page is loading with not hidden content and then I'll do hide() and after that show() id console then it works perfectly. What am I doing wrong?
$(document).ready(function() {
$('.content-flowers').hide()
var first = $(".content-flowers").children()[0];
var second = $(".content-flowers").children()[1];
var third = $(".content-flowers").children()[2];
var firstImg = $(".flower-image")[0];
var secondImg = $(".flower-image")[1];
var thirdImg = $(".flower-image")[2];
$(firstImg).click(function(){
$(first).toggle(1000);
})
/*$(".flower-image").click(function () {
$('.content-flowers').show(1000);
});*/
});
Last commented function works also good, but that function loads all three divs with content, I want in order to after click on 1 image the first div with content will display
You've said the commented-out version works other than that it does all three at the same time, but the earlier version does not work.
They do very different things. Your un-commented-out code looks at the children of the .content-flowers elements:
var first = $(".content-flowers").children()[0];
But your commented-out version works on the .content-flowers elements themselves:
$('.content-flowers').show(1000);
I suspect it's the .children() part that's making it fail. I think you want:
var first = $(".content-flowers")[0];
// No .children() here ----------^
...as the minimal change.
That said, though, the whole thing can be dramatically simpler:
$(document).ready(function() {
$('.content-flowers').hide()
// Get the flower images
var images = $(".flower-image");
// When a flower image is clicked...
images.on("click", function() {
// Determine its index relative to the others...
var index = images.index(this);
// And show that content
$(".content-flowers").eq(index).toggle(1000);
});
});
You already applied the jquery function on the variable first. So try first.toggle(1000) instead. Remove the $ sign.
I just found out that my script is working fine in Chrome, but not in FireFox - and I can't figure out why.
This is the site in development: www.fireflycovers.com
The script should execute when one of the round green buttons is clicked. (scrolls the window to the next container)
The script looks like this at the moment:
$('.scroll').css('display' , 'block');
$('.scroll').on('click', function(e) {
var container = $(this).parent();
// Scans if last container in group
while (document != container[0] &&
container.find('~.col, ~:has(.col)').length == 0) {
// If so, search siblings of parent instead
var container = container.parent(),
nextdiv = container.nextAll('.col, :has(.col)').first();
}
// Back to first .col (when no next .col)
if (nextdiv.length == 0) {
nextdiv = $(document).find('.col:first')
};
// Animates scrolling to new position
$('body').animate({scrollTop:nextdiv.offset().top}, 1000);
return false;
});
});
Did you try debugging at all? As in, putting console.log statements throughout your method to see what the values of things are at certain times and watching it execute? Anyway, does using this help at all?
$('body,html').animate({scrollTop:nextdiv.offset().top}, 1000);
Verified from Animate scrollTop not working in firefox
You need html because firefox behaves differently when it comes to overflow.
Back from this issue
Multiple Dialog
I was able to solve the issue but now problem is that it removes the div so when I access that Div it give error. It gives error because when I open dialog it works fine after removing on close it gives e.rror
I don't want to removed jQuery('#divPopup') If there is only one div present. If multiple jQuery('#divPopup') are there remove() should be working fine.
jQuery('.register_button_class').live('click',function () {
var iFrameobj = createIframe('',iframeUrl);
jQuery('#divPopup').html(iFrameobj);
createDialogWithClose(url,'#bodyId');
return false;
});
Dummy Div for Dialog Popup, This get removed, when Click on Close Jquery Ui Popup.
So when I say
jQuery('#divPopup').html(iFrameobj);
It gives error.
<div id="divPopup"></div>
I'm assuming that your function:
createDialogWithClose(url, '#bodyId');
removes the div id="divPopup" each from the DOM when you close it.
I would suggest not initially including that div in your markup and change your function to create the div and append it to the DOM when it runs. Then remove like you're already doing.
jQuery('.register_button_class').live('click',function () {
var iFrameobj = createIframe('',iframeUrl);
jQuery("body").append("<div id='divPopup' />").html(iFrameobj);
createDialogWithClose(url,'#bodyId');
return false;
});
It's hard to tell what other issues you may be running into with this bit of code that you posted, however, jQuery("body").append("<div id='divPopup' />").html(iFrameobj); will create the divPopup each time the function runs. So, when you close it and it gets removed it will just get created again the next time that button is clicked.
EDIT: How to check if a Div exists -
if ($("#divPopup").length > 0){
// do something here
}
I solved like this
var length = jQuery('#divPopup').length;
if(length>1)
{
jQuery('#divPopup').dialog('destroy').remove();
}else
{
jQuery('#divPopup').dialog('destroy');
}