How to trigger a click event inside iframe?
Challenge: we control code outside iframe and would like to trigger iframe button click
Solution: use the javascript contentWindow property, select an element and trigger the click
Iframes are useful, we can add a weather widget, map or list of recent news using external site iframe. Adding iframe to your website is easy, just copy and paste HTML code with a proper src value. What about interacting with iframe content? It’s not so easy, and sometimes not even possible, but we will try our best to show you how to use iframe click event.
Iframe modifications are possible for iframes from the same domain. There can be situations when we would like to customize iframe content or trigger some actions from outside the iframe window. In this tutorial, we will learn how to: force a button that is outside iframe – click a button placed inside iframe.
Demo with iframe
To demonstrate, we are going to create a simple HTML document with the iframe window added. Iframe will have the button: “Toggle div” that will show/hide hidden div. In the main document, we will place an additional button – “Button outside”. Our goal here is: on button click – we trigger the “Toggle div” button placed inside iframe.
The Main HTML file with iframe:
<!-- demo1.html -->
<html>
<head>
<style>
#myIframe {
height: 300px;
width:100%;
border: 2px solid #999;
}
.main {
display: flex;
flex-wrap: wrap;
}
#myButton {
margin:20px;
}
.col1 {
flex: 1;
}
</style>
</head>
<body>
<div class="main">
<div class="col1">
<iframe id="myIframe" src="iframe1.html"></iframe>
</div>
<div class="col1">
<button id="myButton" onclick="triggerClickInsideIframe()">Button outside</button>
</div>
</div>
<script>
function triggerClickInsideIframe() {
document.getElementById("myIframe").contentWindow.document.getElementById("toggleDivButton").click();
}
</script>
</body>
</html>
Content of the iframe:
<!-- iframe1.html -->
<html>
<head>
<style>
body {
background:yellowgreen;
}
#myDIV{
background:yellow;
border:3px solid brown;
padding:50px;
margin:10px 0;
}
</style>
</head>
<body>
<h1>Iframe content</h1>
<button type="button" id="toggleDivButton" onclick="toggleDiv()">Toggle div</button>
<div id="myDIV" style="display:none;">Hidden content</div>
<script>
function toggleDiv() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
</body>
</html>
Interacting with iframe content by iframe button click event
Iframe button click event (click a button placed inside iframe) is possible by adding custom javascript in the main document. After selecting iframe, the contentWindow property returns iframe DOM that we can interact with.
An example of clicking the iframe button:
<script>
function triggerClickInsideIframe() {
document.getElementById("myIframe").contentWindow.document.getElementById("toggleDivButton").click();
}
</script>
Changing iframe content
Sometimes, we would like to change the content of iframe or hide some elements inside. We are going to add two buttons: “Change iframe background” and “Hide iframe button” that will append CSS styles to iframe.
<!-- demo2.html -->
<html>
<head>
<style>
#myIframe {
height: 300px;
width:100%;
border: 2px solid #999;
}
.main {
display: flex;
flex-wrap: wrap;
}
.btn {
margin:20px;
}
.col1 {
flex: 1;
}
</style>
</head>
<body>
<h2>Demo2</h2>
<div class="main">
<div class="col1">
<iframe id="myIframe" src="iframe1.html"></iframe>
</div>
<div class="col1">
<button id="myButton2" class="btn" onclick="changeIframeBackground()">Change iframe background</button>
<br>
<button id="myButton3" class="btn" onclick="hideIframeButton()">Hide iframe button</button>
</div>
</div>
<script>
function triggerClickInsideIframe() {
document.getElementById("myIframe").contentWindow.document.getElementById("toggleDivButton").click();
}
</script>
<script>
function changeIframeBackground(){
let head = document.getElementById("myIframe").contentWindow.document.head || document.getElementById("myIframe").contentWindow.document.getElementsByTagName('head')[0];
let style = document.createElement('style');
let css = "body{background:orange !important;}";
head.appendChild(style);
style.appendChild(document.createTextNode(css));
}
function hideIframeButton(){
let head = document.getElementById("myIframe").contentWindow.document.head || document.getElementById("myIframe").contentWindow.document.getElementsByTagName('head')[0];
let style = document.createElement('style');
let css = "#toggleDivButton {display:none}";
head.appendChild(style);
style.appendChild(document.createTextNode(css));
}
</script>
</body>
</html>
Bonus: iframe load javascript event
There is a handy on load event, which can be used to append content inside the iframe window. It is triggered when iframe is loading. If you would like to make permanent changes to iframe, here is the suggested scenario: display the animated loader, modify iframe using javascript, after completion – hide the loader.
In demo3, we are going to use the iframe load event and change the body background. In addition, we will append a custom header with the text: Appended text using JS.
<!-- demo3.html -->
<html>
<head>
<style>
#myIframe {
height: 300px;
width:100%;
border: 2px solid #999;
}
.main {
display: flex;
flex-wrap: wrap;
}
.btn {
margin:20px;
}
.col1 {
flex: 1;
}
</style>
<style>
#iframe-wrapper1.is-loading {
width:100%;
background-repeat: no-repeat;
background-position: center center;
background-image: url(data:image/gif;base64,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);
}
#iframe-wrapper1.is-loading iframe {
visibility: hidden;
}
</style>
</head>
<body>
<h2>Demo3</h2>
<div class="main">
<div class="col1">
<div id="iframe-wrapper1" class="is-loading">
<iframe id="myIframe" src="iframe1.html"></iframe>
</div>
</div>
</div>
<script>
document.getElementById('myIframe').onload = function() {
let head = document.getElementById("myIframe").contentWindow.document.head || document.getElementById("myIframe").contentWindow.document.getElementsByTagName('head')[0];
let body = document.getElementById("myIframe").contentWindow.document.body || document.getElementById("myIframe").contentWindow.document.getElementsByTagName('body')[0];
let style = document.createElement('style');
let css = "body{background:red !important;} #toggleDivButton {display:none}";
let header = "<h1 style='color:yellow'>Appended text using JS</h1>";
head.appendChild(style);
style.appendChild(document.createTextNode(css));
body.innerHTML += header;
setTimeout(function(){
document.getElementById("iframe-wrapper1").classList.remove("is-loading");
},2000);
};
</script>
</body>
</html>
Cross-origin frame
What about using iframe, but from a different domain? For example, a Wikipedia article. Let’s try it:
<div id="iframe-wrapper1">
<iframe id="myIframe" src="https://en.wikipedia.org/wiki/Sociable_weaver"></iframe>
</div>
Iframe onload displays the following error:
Uncaught DOMException: Blocked a frame with origin “http://localhost:63342” from accessing a cross-origin frame. at document.getElementById.onload
What is the reason? Same-origin policy which is a critical security mechanism. It prevents a malicious website from running Javascript code on a third-party website. Two URLs have the same origin if the protocol and host are the same for both. If the port if specified, it also should match.
To sum up, when we load iframe from the same domain, we can modify it, otherwise – we cannot.
Source code of javascript iframe events
The demos presented in this tutorial can be downloaded from github. Make sure to load files using the server (localhost or normal server), otherwise iframe may not work. Repository: https://github.com/createit-dev/166-how-to-click-programmatically-button-inside-iframe
That’s it for today’s tutorial. Subscribe to our newsletter to stay up-to-date with other useful tips and guidelines.
Do you need someone to implement this solution for you? Check out our specialists for hire in the outsourcing section.
Are you considering a global project and are uncertain how to proceed? See our custom web application development section and see how we do it!