Apply "onclick" to all elements in an iFrame - iframe

How do I use the JavaScript DOM to apply onclick events to links inside of an iframe?
Here's what I'm trying that isn't working:
document.getElementById('myIframe').contentDocument.getElementsByTagName('a').onclick = function();
No errors seem to be thrown, and I have complete control of the stuff in the iframe.
Here is some code to test and see if I can at least count how many div's are in my iframe.
// access body
var docBody = document.getElementsByTagName("body")[0];
// create and load iframe element
var embed_results = document.createElement('iframe');
embed_results.id = "myIframe";
embed_results.setAttribute("src", "http://www.mysite.com/syndication/php/embed.php");
// append to body
docBody.appendChild(embed_results);
// count the divs in iframe and alert
alert(document.getElementById("myIframe").contentDocument.getElementsByTagName('div').length);

It is possible for an iFrame to source content from another website on a different domain.
Being able to access content on other domains would represent a security vulnerability to the user and so it is not possible to do this via Javascript.
For this reason, you can not attach events in your page to content within an iFrame.

getElementsByTagName returns a NodeCollection, so you have to iterate throgh this collection and add onclick handler to every node in that collection. The code below should work.
var links = document.getElementById('myIframe').contentDocument.getElementsByTagName('a');
for(var i=0;i<links.length;++i)links[i].onclick=function(){}
also make sure, you run this code after the frames' content is loaded
embed_results.onload=function(){
// your code
}

Related

How do I scrape for links to webpages which gets opened in another tab on clicking an HTML element using Scrapy and Playwright?

I want to scrape this link : https://www.magicbricks.com/property-for-sale/residential-real-estate?bedroom=&proptype=Multistorey-Apartment,Builder-Floor-Apartment,Penthouse,Studio-Apartment&cityName=Mumbai for the links for each property.
The link to the individual pages for each property is not in the HTML source code. The opening of the page instead is linked to an event. How do I get the links to the page that opens using Scrapy and Playwright?
Each website is different and needs to be treated differently. Usually the journey starts from the element panel of the page.
Upon taking a closer look at the elements panel of the url you have shared, we can see each card is inside a div and the div also has a script tag with a json. The json indeed has the URL you were looking for.
Here is the code to extract the URLs that you can run inside the page.evaluate function.
await page.evaluate(async () => {
const urls = [];
// parent card elements
var cardElements = [...document.querySelectorAll('[class="mb-srp__list"]')];
for(let cardElement of cardElements) {
// get nested script tag inside each card element that contains the url
const script = cardElement.querySelector('script');
// but the content of the tag is a string, so we need to parse
const cardJSON = JSON.parse(script.innerHTML);
// finally save whatever data we want
urls.push(cardJSON.url);
}
return urls;
});
Here is a shorter version of the code that can go inside page.evaluate,
[...document.querySelectorAll('[class="mb-srp__list"]')].map(card=>JSON.parse(card.querySelector('script').innerHTML).url)

iframe cross-domain access with JavaScript

I have a simple HTML page with an iframe. I set its src to another HTML
file and I can change the style of any chosen element at will using code
like this (a basic example):
function elementStyle()
{
var iFrame = document.getElementById( "iFrame" );
var element = iFrame.contentWindow.document.getElementsByTagName(
"table" )[0];
element.style.color = "#ff0000";
}
However the src of the iframe must be an external URL and cross-domain
restriction prevents me from accessing its elements. I have no control
over its content so I can't use postMessage() because I can't receive
any message posted.
Any ideas of a way to get round this?
Note: it must work for anyone with any browser so musn't use any special
methods (like jQuery, CORS etc).
Thanks

iframe window top location issue. iframe loads over and over again

When my iframe loads I need parent page to load different content(header,footer) while iframe its still there. I added to iframe :
window.top.location = "http://mysite.com";
It loads the new parent page but its reloading over and over again.
How can I enable only one load/iframe load, or some solution.
I have tried with
window.onload = function() {
if(!window.location.hash) {
window.location = window.location + '#loaded';
window.location.reload();
}
}
but it does nothing.
Thank you.
you just can't reload the iframe parent only without reloading the iframe too! If you want to change some content in parent page you must do it with javascript from the parent page and not the iframe.
And if you want to catch the "iframe loaded event" you must do it from inside the iframe. Looks like an impossible situation but you can still do it!
You need to let iframe and parent page comunicate, and you can do it with html5 postmessage (works even if parent and iframe are in different domains!). If you need to have IE7 compatibility too you can use easyXDM javascript library instead of postMessage, just search for example in their site.
Simply do a postMessage from iFrame when jQuery(document).ready() (or any similar event) is triggered, the parent page must have a listner waiting for this message for trigger the header/footer/anything change event.

How to detect the load event of iframe which is inside a html scope from the outside of iframe(parent html)

a few notes:
1.i can not modify the iframe content to add the onload= function
2.the iframe has an id.
3.the iframe has no callback to its parent html page.
4.I use the prototype ,not jquery, for some old reasons.
i wanna do something when the iframe load finished.
but, i have tried the
document.observe('dom:loaded',function()
{
alert($('iframe-id')); >> **IS NULL**
})
and
Event.observe(window,'load',function(){..
alert($('iframe-id')); >> **IS NULL STILL**
...})
Did i miss some methods in prototype or javascript?
Thanks.

Auto ajax selectors with Jquery

I'm trying to make a proof of concept website, but I want perfect degradation. As such I'm going to code the website in plain XHTML first and then add classes & ids to hook them in jQuery.
One thing I want to do is eventually enable Ajax xmlhttprequest for all my links, so they display in a viewport div. I want this viewport to be a "universal" dump for any xmlhttprequest from multiple external pages.
I was wondering if I'm able to hardcode something like:
<a href="blah.html" class="ajax">, <a href="bleat.html" class="ajax">
etc. So as you can see, I give all link tags that I want to call Ajax requests from with the class ajax. In my JS based on jQuery, I want to be able to code it such that all positive ${"a").filter(".ajax") will automatically load their respective hrefs [variable] as a ajax request.
Please help. I'm a n00b.
With your example, you should be able to do:
$('.ajax').click(function () {
// Your code here. You should be able to get the href variable and
// do your ajax request based on it. Something like:
var url = $(this).attr('href');
$.ajax({
type: "GET",
url: url
});
return false; // You need to return false so the link
// doesn't actually fire.
});
I would suggest using a class different from "ajax" because it makes the code a little strange to read, because $('.ajax') could be misread as $.ajax().
The $('.ajax').click() part registers an onClick event handler for every element on the page with the class "ajax" which is exactly what you want. Then you use $(this).attr('href') to get the href of the particular link clicked and then do whatever you need!
Something like:
function callback(responseText){
//load the returned html into a dom object and get the contents of #content
var html = $('#content',responseText)[0].innerHTML;
//assign it to the #content div
$('#content').html(html);
}
$('a.ajax').click(function(){
$.get(this.href, callback);
return false;
});
You need to parse out everything that is outside of the #content div so that the navigation isn't displayed more than once. I was thinking about a regexp but probable easier to use jQuery to do it so I updated the example.

Resources