Javascript DOM send value to function embedded in iframe to simulate keypress - javascript

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);
});

Related

Detect Swipe gesture from iframe

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.

Need javascript to auto-scroll to the target html element after page loads

I'm backend developer, new to javascript. Can anyone provide a few lines of script that will allow the page to auto-scroll to the "target" element after the page loads
<html>
<bod>
<p id="target">...</p> // auto-scroll here
</bod>
</html>
Thanks
You can use scrollIntoView on the element in window.onload event..
In your case you would be doing:
window.onload = function() {
var el = document.getElementById('target');
el.scrollIntoView(true);
}
Good docs can be found here:
MDN scrollIntoView
Also change your body tag to something like
<body onload="ScrollToTarget">
Then your function can be defined in the header as
function ScrollToTarget()
{
document.getElementById("target").scrollIntoView(true);
}

How to add a click event to p elements in iframe (using jQuery)

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.

Capture iframe load complete event

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/

How can you set focus to an HTML input element without having all of the HTML?

First, the background:
I'm working in Tapestry 4, so the HTML for any given page is stitched together from various bits and pieces of HTML scattered throughout the application. For the component I'm working on I don't have the <body> tag so I can't give it an onload attribute.
The component has an input element that needs focus when the page loads. Does anyone know a way to set the focus to a file input (or any other text-type input) on page load without access to the body tag?
I've tried inserting script into the body like
document.body.setAttribute('onload', 'setFocus()')
(where setFocus is a function setting the focus to the file input element), but that didn't work. I can't say I was surprised by that though.
EDIT:
As has been stated, I do indeed need to do this with a page component. I ended up adding file-type inputs to the script we use for giving focus to the first editable and visible input on a page. In researching this problem I haven't found any security issues with doing this.
<script>
window.onload = function() {
document.getElementById('search_query').select();
//document.getElementById('search_query').value = '';
// where 'search_query' will be the id of the input element
};
</script>
must be useful i think !!!
This has worked well for me:
<script>
function getLastFormElem(){
var fID = document.forms.length -1;
var f = document.forms[fID];
var eID = f.elements.length -1;
return f.elements[eID];
}
</script>
<input name="whatever" id="maybesetmaybenot" type="text"/>
<!-- any other code except more form tags -->
<script>getLastFormElem().focus();</script>
you can give the window an onload handler
window.onload = setFocus;
I think you have a fundamental problem with your encapsulation. Although in most cases you could attach an event handler to the onload event - see http://ejohn.org/projects/flexible-javascript-events/ by John Resig for how to do this, setFocus needs to be managed by a page component since you can't have two components on your page requiring that they get the focus when the page loads.
Try play with tabstop attribute
First of all, the input file is no the same as the other inputs, you need to keep this in mind.... thats for security reasons. When the input file get focus it should be read only or the browser should popup a dialog to choose some file.
Now, for the other inputs you could try some onload event on some of your elements...(not only the body have the onload event) or you could use inline javascript in the middle of the html. If you put javascript code without telling that is a function it gets executes while the browser reads it. Something like:
<script type="text/javascript">
function yourFunction()
{
...;
};
alert('hello world!");
yourFunction();
</script>
The function will be executed after the alert just when the browser reads it.
If you can, you should use jQuery to do your javascript. It will make your live soooo much easy.... :)
With jQuery could be done like this:
$(function() {
$("input:file").eq(0).focus()
})
With plain javascript could be done like this:
var oldWindowOnload = window.onload; // be nice with other uses of onload
window.onload = function() {
var form = document.forms[0];
for(i=0; i < form.length; i++) {
if (form[i].type == "file") {
form[i].focus();
}
}
oldWindowOnload();
}
For more elaborate solution with plain javascript see Set Focus to First Input on Web Page on CodeProject.
Scunliffe's solution has a usability advantage.
When page scripts are loading slowly, calling focus() from "onLoad" event makes a very nasty page "jump" if user scrolls away the page. So this is a more user friendly approach:
<input id="..."></input>
... really small piece of HTML ...
<script>getTheDesiredInput().focus();</script>

Categories

Resources