I am loading local HTML file in IFrame using HTML/Javascript in windows store development(Windows 8). I am trying get Swipe event from Iframe.
I tried with this sample & this. I fallowed the Mouse wheel scenario which contains one div element.
For Iframe it doesn't work.
My code:
<body>
<iframe id="iframe_Id" src="split.html" style="height:768px; width:1366px;" onload="Load();"></iframe>
</body>
function Load() {
var elt = document.getElementById("iframe_Id");
elt.style.backgroundColor = "#f3f3f3";
var gobj = new MSGesture();
// Defining gesture object for Pen, mouse and touch
gobj.target = elt;
elt.gesture = gobj;
elt.gesture.pointerType = null;
// Creating event listeners for gesture elements
elt.addEventListener("MSPointerDown", onPointerDown, false);
elt.addEventListener("MSGestureTap", onTap, false);
elt.addEventListener("MSGestureHold", onHold, false);
elt.addEventListener("MSGestureChange", onGestureChange, false);
// Mouse Wheel does not generate onPointerUp
elt.addEventListener("MSGestureEnd", onGestureEnd, false);
}
function onPointerDown(e) {
var content = document.getElementById("iframe_Id");
}
I created functions for all the events. But when swipe in my IFrame the event not raised.
I structured here. I need to work with Swipe. Please help me to out from this.
If split.html is a local file, you should listen for the events from within the iframe. You can then use parent.postMessage() to communicate up to the host/parent HTML page.
Alternatively, you can investigate the new WebView control available to HTML/JavaScript apps in Windows 8.1.
You should put your <iframe> inside a <div> block, like this :
<body>
<div id="watch">
<iframe id="iframe_Id" src="split.html" style="height:768px;
width:1366px;" onload="Load();">
</iframe>
</div>
</body>
And then you look the swipe in the div#watch instead of the iframe, because the touch event will be in the DOM and not in the iframe.
Related
in the web-app I'm developing I'd need to dynamically create/remove iframe elements and to catch the corresponding remove events.
This is the relevant html:
index.html
<main>
[..]
<iframe id="iframe_id" width="700" height="650" src=""></iframe>
<div class="theday" id="js-theday"></div>
[..]
</main>
<script src="app.js"></script>
<script type="text/javascript">
function closeIFrame() {
$('#iframe_id').remove();
}
[..]
</script>
In app.js I'm catching the remove event sent in closeIFrame()
$('#iframe_id').on('DOMNodeRemoved', function() {
}
In the first run, when the iframe calls parent.closeIFrame(), app.js receives correctly the
DOMNodeRemoved and do stuffs.
At some point, I'd need to recreate the iframe element. In app.js
function recreate_iframe_html() {
const target = document.querySelector('#js-theday');
var new_iframe = document.createElement('iframe');
new_iframe.setAttribute('id', 'iframe_id');
new_iframe.width = 700;
new_iframe.height = 650;
new_iframe.src = '';
target.parentNode.insertBefore(new_iframe, target);
}
[..]
recreate_iframe_html();
When the new iframe calls parent.closeIFrame(), the iframe is correctly removed but app.js does not detect the DOMNodeRemoved event.
Why is that?
Thank you for your help.
.on('DOMNodeRemoved') only works on the items returned by the query (that is, #iframe_id). It does not stick around to listen to newly created items with the same id.
You need to add another listener when creating the new iframe.
I just figured out how to detect click event on a cross domain iframe but it's only working for desktop, the following code works when detecting the click event inside the iframe, however, I also need it to work on mobile devices, I tried to use the touchstartand touchendevents to add mobile support to this script, but it's not working.
//Google ADs track conversion
$( document ).ready(function() {
var iframeMouseOver = false;
var iframeTouched = false;
$("#wh-widget-send-button")
.off("mouseover.iframe").on("mouseover.iframe", function() {
iframeMouseOver = true;
})
.off("mouseout.iframe").on("mouseout.iframe", function() {
iframeMouseOver = false;
});
//Add mobile support to this script
$("#wh-widget-send-button")
.off("touchstart").on("touchstart", function() {
iframeTouched = true;
})
.off("touchend").on("touchend", function() {
iframeTouched = false;
});
$(window).off("blur.iframe").on("blur.iframe", function() {
if(iframeMouseOver || iframeTouched){
console.log("Iframe Clicked");
gtag_report_conversion();
}
});
});
UPDATE
The HTML as requested, it's just a simple iframe inside a div, also cleared the above code a bit to focus on the important part:
<div id="wh-widget-send-button">
<iframe src="http://anyexternaldomain.com"></iframe>
</div>
I am not sure why you need to check for hover or touch. You can just check for click and perform the action.
The main concept is to remove event handling from iframe by assigning pointer-events:none;. This will make the parent element wh-widget-send-button receive all events and then you can handle them as needed.
You can try this code:
$(document).ready(function() {
$("#wh-widget-send-button").off("click").on("click", function() {
console.log("Clicked");
// gtag_report_conversion();
});
});
iframe
{
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wh-widget-send-button">
<iframe src="http://anyexternaldomain.com"></iframe>
</div>
Unfortunately, what you are trying to do is impossible. The developers of web browsers have purposefully made it so, in order to avoid the malicious practice of clickjacking. You cannot catch a click that goes into an iframe. What you are currently doing on desktop is only tracking whether the mouse hovers over the iframe, not whether it is actually clicked. Unfortunately, you cannot do even this on mobile, because the touch on the touchscreen is automatically transmitted to the iframe, there is no such concept as "hover" as it applies to touch screens. Sorry to drop bad news on you.
I have a test that I have been working on, trying to send a value to a function defined within an iframe (both pages from the same source). The content of the iframe when in focus responds to certain keystrokes. What I would like to achieve is triggering those keypress actions from the iframe by means of a button on the primary page.
The content of the iframe is dynamic, and needs to function without refreshing, otherwise I know I could change the iframe src to carry the variables. What I have so far...
Parent Page:
<!DOCTYPE html><html><head>
<style>
iframe{border:1px solid blue;height:100px;width:100px;margin:20px auto 0 auto;}
</style>
</head><body>
<iframe id="iframe" src="iframetest2.html"></iframe>
<button onclick="simKey(32);">CLICK</button>
<script>
var iframe=document.getElementById('iframe');
var ifContent=iframe.contentWindow
function simKey(x){
ifContent.postMessage(testScript(x),'*','[transfer]');
}
</script></body></html>
And the iFrame content:
<!DOCTYPE html><html><head>
<script>
function testScript(x){
document.body.innerHTML=x;
setTimeout(function(){document.body.innerHTML='';},700);
}
</script></head><body onkeypress="testScript(event.keyCode)"></body></html>
I am also trying to avoid the use of jQuery if possible. This is a concept web design, and really want to hand-write the Javascript so that I can modify as need be.
First, inline js (like onkeypress in your html) is a bad practice. Read some these results: https://www.google.com/search?q=Why+is+inline+js+bad%3F
I will be using the best practice addEventListener.
Fire iFrame keypress event from button on parent window:
Live demo (click).
Main Page:
var myBtn = document.getElementById('myBtn');
var iframe = document.getElementById('myIframe');
myBtn.addEventListener('click', function() {
var evt = new Event('keypress');
evt.keyCode = '115';
iframe.contentDocument.body.dispatchEvent(evt);
});
iFrame:
document.body.addEventListener('keypress', function(e) {
console.log(e.keyCode);
});
Here are some docs that might help you if you need to support older browsers or want more information: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
Old Answer: this listens to keypresses on the parent window.
In the iFrame, you just need to have this JavaScript:
window.parent.document.body.addEventListener('keypress', function(e) {
console.log(e.keyCode);
});
How to add a click event to <p> elements in iframe (using jQuery)
<iframe frameborder="0" id="oframe" src="iframe.html" width="100%" name="oframe">
There's a special jQuery function that does that: .contents(). See the example for how it's works.
Your best best bet is to invoke the iframe AS LONG AS it's part of your domain.
iframe.html
<html>
<head>
<script>
window.MyMethod = function()
{
$('p').click();
}
</script>
</head>
<body></body>
</html>
And then use
document.getElementById('targetFrame').contentWindow.MyMethod();
To invoke that function.
another way is to access the iframe via window.frames.
<iframe name="myIframe" src="iframe.html"/>
and the javascript
child_frame = window.frames['myIframe'].document;
$('p',child_frame).click(function(){
alert('This click as bound via the parent frame')
});
That should work fine.
Wanted to add this, as a complete, copy-paste solution (works on Firefox and Chrome). Sometimes it is easy to miss to remember to call the event after the document, and so the iframe, is fully loaded:
$('#iframe').on('load', function() {
$('#iframe').contents().find('#div-in-iframe').click(function() {
// ...
});
});
The iframe must be on the same domain for this to work.
By giving a reference to the IFrame document as the second parameter to jQuery, which is the context:
jQuery("p", document.frames["oframe"].document).click(...);
To access any element from within an iframe, a simple JavaScript approach is as follows:
var iframe = document.getElementById("iframe");
var iframeDoc = iframe.contentDocument || iframe.contentWindow;
// Get HTML element
var iframeHtml = iframeDoc.getElementsByTagName("html")[0];
Now you can select any element using this html element
iframeHtml.getElementById("someElement");
Now, you can bind any event you want to this element. Hope this helps. Sorry for incorrect English.
Is there a way to capture when the contents of an iframe have fully loaded from the parent page?
<iframe> elements have a load event for that.
How you listen to that event is up to you, but generally the best way is to:
1) create your iframe programatically
It makes sure your load listener is always called by attaching it before the iframe starts loading.
<script>
var iframe = document.createElement('iframe');
iframe.onload = function() { alert('myframe is loaded'); }; // before setting 'src'
iframe.src = '...';
document.body.appendChild(iframe); // add it to wherever you need it in the document
</script>
2) inline javascript, is another way that you can use inside your HTML markup.
<script>
function onMyFrameLoad() {
alert('myframe is loaded');
};
</script>
<iframe id="myframe" src="..." onload="onMyFrameLoad(this)"></iframe>
3) You may also attach the event listener after the element, inside a <script> tag, but keep in mind that in this case, there is a slight chance that the iframe is already loaded by the time you get to adding your listener. Therefore it's possible that it will not be called (e.g. if the iframe is very very fast, or coming from cache).
<iframe id="myframe" src="..."></iframe>
<script>
document.getElementById('myframe').onload = function() {
alert('myframe is loaded');
};
</script>
Also see my other answer about which elements can also fire this type of load event
Neither of the above answers worked for me, however this did
UPDATE:
As #doppleganger pointed out below, load is gone as of jQuery 3.0, so here's an updated version that uses on. Please note this will actually work on jQuery 1.7+, so you can implement it this way even if you're not on jQuery 3.0 yet.
$('iframe').on('load', function() {
// do stuff
});
There is another consistent way (only for IE9+) in vanilla JavaScript for this:
const iframe = document.getElementById('iframe');
const handleLoad = () => console.log('loaded');
iframe.addEventListener('load', handleLoad, true)
And if you're interested in Observables this does the trick:
import { fromEvent } from 'rxjs';
const iframe = document.getElementById('iframe');
fromEvent(iframe, 'load').subscribe(() => console.log('loaded');
Note that the onload event doesn't seem to fire if the iframe is loaded when offscreen. This frequently occurs when using "Open in New Window" /w tabs.
Step 1: Add iframe in template.
<iframe id="uvIFrame" src="www.google.com"></iframe>
Step 2: Add load listener in Controller.
document.querySelector('iframe#uvIFrame').addEventListener('load', function () {
$scope.loading = false;
$scope.$apply();
});
You can also capture jquery ready event this way:
$('#iframeid').ready(function () {
//Everything you need.
});
Here is a working example:
http://jsfiddle.net/ZrFzF/