Receiving touchmove events when scrolling a child iframe - javascript

I'm developing a mobile-designed webapp which loads content into an internal iframe. This frame updates its height every time new content is loaded to avoid scrolling inside the iframe. In that way I have a long iframe which is scrolled in the context of the main webapp. This is currently working well in Safari and Chrome for iOS. The most simple example of the app structure is:
<div id="header">
<p>Scroll: <span id="scroll"></span></p>
<p>Touchmove: <span id="touchmove"></span></p>
</div>
<iframe src="https://developer.android.com/about/dashboards/index.html" class="frame-style" id="uframe"></iframe>
In order to trigger certain visual effects I need to know the current Y-axis position of the application's content. I'm using Jquery's bind function to receive touchmove events from touch devices. Scroll events are not very useful since on mobile devices they are only triggered at the end of the scrolling, I need to know the position of the Y-axis every time it has been changed by scrolling. Unfortunately I discovered touchmove events aren't triggered when scrolling starts touching the iframe's contents. I'm using these statements:
$(window).bind('touchmove',
function(){
console.log('touchmove='+window.pageYOffset); //Show in console
$('#touchmove').html(window.pageYOffset); //Update value in document
});
So the question is: Is there any way to receive touchmove events when scrolling a child iframe?
The running example can be checked on: http://jsfiddle.net/badger_cl/b9322/1/
To try it on a mobile device you can access: http://fiddle.jshell.net/badger_cl/b9322/1/show/light/
The red stripe is a div element, when the touch-scrolling starts from this element, it updates the touchmove value. When the scrolling starts at the iframe content (The Android dashboard in this case), it doesn't update the touchmove value. Scroll updates are shown just to demonstrate it only updates at the end of the scrolling.

You can listen to touchmove event both on parent page and on page loaded into the iframe.
Next you will need to communicate from iframe to parent window that touchmove event happened. You can use Window.postMessage method for this.
Send message from iframe:
window.parent.postMessage(messageObj);
Receive message in parent window:
window.addEventListener('message', function (event) {
var messageObj = event.data;
});
Documentation: https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage

Related

Bubble up mousemove event on iframe to the container div

I have the following code
<div onmousemove="myFunction()">
<iframe src="www.someotherdomain.com"/>
</div>
I want myFunction to be executed when user moves his mouse over the iframe. Is it possible to bubble up the events on iframe to the parent element in cross domain scenario? How will I do this?
PS:-
I can't use the solution provided in
Iframe obstructing the mousemove event from occuring
or
How do you send a mousemove event from an iframe back to the parent using jquery?
because I want the user to be able to interact with the content in the iframe.
I can see only one way.
Disable the session timer when mousing into the iframe and enable it when mousing out.
To do this, add a margin in the div and use mouseenter plus mouseleave from the outer div and vice versa on the way out.
If the window loses focus you may also want to enable the timer

How to force an iframe's parent page to scroll to top automatically when the user navigates in the iframe?

* Please note: cross-domain scenario *
I have an iframe which has no scrollbar, but much more taller than the browser window, so the vertical scrolling is done by the browser's main vertical scrollbar. However there is a disturbing feature of this: When the navigation done in scrolled down state the scroll is not reset to top in the parent.
I would like to reset this scroll to the init top state automatically when page navigation occurs in the iframe.
Thanks in advance.
If your iframe has a cross domain issue (pointing to somewhere other than your website) You can't:
error : Permission denied to access property 'document'
But if not, you can do it using this code. add this to scripts in page:
var myframe = window.frames[0].window;
myframe.onscroll = function(){if(myframe.scrollY == myframe.scrollMaxY){window.scrollTo(0,0);}};
//Thanks Diodeus!
Or you can select it by getElementById or other similars and give the reference to myframe variable. This triggers an event when you scroll down in the iframe and then scrolls the whole document up.
You can hook an onload event to the iframe. It is one of the few hooks you can get in a cross-domain scenario.
document.getElementById("some_iframe").onload = function (){ window.scrollTo(0,0); }

Stop full page to scroll in ipad web app

I have ipad web app i am scrolling the particular div it is working fine but problem is that when user touces out side the div then also the page scrolls i want to stop the page scroll and make div only to scroll.
I used
document.ontouchmove=function(e) { e.preventDefault()};
but it stops scrolling on whole page also on div.
here is the index file link i am working on
http://codepad.org/7RE5vx74
Give the div a class (say, 'scrollThis'). Handle the touchmove event in such a way that, if the target of the touchmove event is not the div, to prevent the scroll. Else, let it take place.
$('body').on('touchmove', function (e) {
if (!$('.scrollThis').has($(e.target)).length) //check if the div isn't being scrolled
e.preventDefault();
});
I have used this in an iOS/android web app, so i can vouch that it works.

How to catch scroll event inside facebook canvas frame?

I am trying to catch when a user scrolls canvas iframe of facebook app. I tried:
$(window).scroll(...)
$(document).scroll(...)
$(parent).scroll(...)
$(parent.document).scroll(...)
but it doesn't fire.
I think you mean catch when the user is scrolling the main page, not the iframe, correct?
You can't do it directly, you will have to use FB.Canvas.getPageInfo as descibed at http://developers.facebook.com/docs/reference/javascript/FB.Canvas.getPageInfo/ . You can't "catch" it as an event, but you can poll the scroll values using setInterval or similar to detect when the page position has changed.
As #Floyd said the scroll events will not fire (assuming you are hiding the iframe scrollbars) as your App is in an iframe inside of Facebook.
You can detect the users scroll position on the page (Facebook, not your app - so it won't be completely accurate unless you take the header and floating header into account) by using FB.Canvas.getPageInfo http://developers.facebook.com/docs/reference/javascript/FB.Canvas.getPageInfo/ but you have to poll the event when ever you want to check the users scroll position, so you could set it up on a timer with setInterval.
I just created a plugin for this purpose to use in one of my Facebook apps. To use it all you simply do is include the plugin after your window.fbAsyncInit function and before you load the Facebook Javascript SDK.
You can subscribe to the Facebook event "scroll" or listen to the dom event "fb-scroll" which two parameters will be passed "topPercent" and "bottomPercent" and then call your own functions based on the users scroll position.
https://github.com/kus/facebook-app-scroll-event
Example:
// Subscribe to custom Facebook event
FB.Event.subscribe('scroll', function(topPercent, bottomPercent){
console.log('scroll', topPercent, bottomPercent);
});
// Listen to dom event with jQuery
jQuery(document).on('fb-scroll', function(evt, topPercent, bottomPercent){
if(bottomPercent == 100){
// load more content
}
});
I think you are not allowed to do this, I guess it's similar to the "Profile Takeover" in the Prohibited Functionality section.
As far as I know, you can only change the parent URL: top.location.href

Resizing iframe when document changes size

I have a web page with an application running in an iframe (same domain). The iframe's height is set on load based on the iframed document's height. The problem is when the iframed document's size is changed (by expanding an accordion, menu etc). Are there any events fired when this occurs, that I can use to resize the iframe element accordingly?
I have tried to bind to the resize event on the window object in the iframe, but as the window isn't resized when the document content changes, the event doesn't fire. What I need is some kind of resize-event on the document object, but as far as I know, there is no such thing. Is there another way to detect changes in the document's height?
I'd appreciate a general solution, as I don't know the content of the iframe exactly, but I can include generic scripts in it.
There are resize events fired for the iframe window. You can listen to them (in the iframe itself) and than trigger some function in the parent window to propagate new size and update the iframe size in the parent window.
Have you tried using the scroll event and attaching it to the contentWindow of the iFrame?
Otherwise I would rather suggest you hook directly into the accordion rather than relying on catching scroll events that may or may not happen.
Because scroll will only fire once the user actually scrolled the slider, not when the accordion expands..
But you could simply call a method on the parent when the user expands the accordion passing it the new size of the accordion.
I found a possible, but not ideal solution, and it doesn't work in all browsers:
By binding to the body element's DOMSubtreeModified in the iframe, I can find the iframe element in parent or top and change it's height.
$('body').bind('DOMSubtreeModified', function(){
top.document.getElementById('appFrame').height = $(document).height();
});
Here's an overview of the browser support for this event:
http://www.quirksmode.org/dom/events/
If you are using jQuery ui then you can use event change and call function
setHeight
http://jqueryui.com/demos/accordion/
function setHeight() {
parent.document.getElementById('the-iframe-id').height = document['body'].offsetHeight;
}

Categories

Resources