How to catch scroll event inside facebook canvas frame? - javascript

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

Related

How To Use 'beforeunload' to Capture Iframe Click?

I am trying to build a code that does a request when a cross-origin iframe is clicked and it directs the main window to a new page.
Since it's impossible to directly tap into Iframe click events, I thought of the following conditions as necessary:
page unload event occurs
the window is out of focus
Page unload (As far as I know) happens only when the current url is directed to some other url.
Now, this unload could happen by clicking any link. To restrict it to Iframes, I added the condition of window being out of focus.
addEventListener('beforeunload',(event) =>{
if(!(document.hasFocus())){
// Do Something
}
});
My question is, are their any limitations to this approach? If yes, then please suggest some more conditions to make it as close to reality.
For those of you, who are curious: I want to track clicks on Google AdSense Iframes on my website.

How to send/dispatch keypress events to an embedded iframe in React?

I have an iframe of Google Slides which I embedded in my web app.
The iframe implementation is:
<iframe ref={slidesRef} src={src} width='100%' height='100%' allowFullScreen={true}/>
I want to listen to click events on the main web page (while the iframe is not necessarily in focus), then create their corresponding keypress events - and pass them to the iframe, thus making the slideshow iframe to trigger and react to the user key presses.
I tried something like this:
function onButtonClick(e) {
e.stopPropagation();
slidesRef.current.focus();
slidesRef.current.dispatchEvent(new KeyboardEvent('keypress', {
key: 'ArrowRight', which : 39
}));
}
But it doesn't work - it only focuses on the iframe, but doesn't send the arrow key event.
I saw some solutions using the parent document inside the iframe or sending messages with postMessage, but I can't add any code inside my iframe since its origin is an external link.
Due to restrictions imposed by the Same Origin Policy implemented by all modern browsers, I don't think you'll be able to do what you intend to do - this is not related to React, the browser will just not allow for a script on the parent window to trigger any kind DOM event on the child iframe programmatically.
That's why you saw references to the postMessage API when you searched for a solution. That API was introduced to enable cross-origin communication between window objects in a safer, more controlled manner.
The code you've posted would execute any event listener that might appended to the parent window's DOM iframe element, so something like this:
<iframe onkeydown="console.log('keydow')" src="https://google/..." />
Should be triggered by your code. But this is happening on the parent window, the javascript "running" within iframe (i.e. Google's code responsible for changing the current slide) doesn't have access nor is able to "see" that event.
If both the iframe and your webpage were serviced from the same domain (in other words, if they had the same "origin"), what I think you're trying to achieve would be something more in the lines of:
function onButtonClick(e) {
e.stopPropagation()
// Note that we're retrieving a DOM element from the iframe's window object,
// not the parent's one
const iframeBody = slidesRef.current.contentDocument.body;
// Get an element on the iframe's document which has an event listener attached
// to it that changes the current slide
const sliderEl = iframeBody.querySelector('...')
sliderEl.click()
}
But again this'd only work if both the iframe and parent window were considered to have the "same origin" by the browser (which isn't your case).
Albeit significantly more complicated, you could probably achieve something close to what you're looking for (at the cost of rebuilding the design of some webpages, at least) by querying Google Slides using the corresponding Google API.
Check out the corresponding documentation: https://developers.google.com/slides/quickstart/javascript
It may look scary at first, but once you've got used to it, Google APIs don't bite that much, you can even create a service account and grant it access to your document so that your app can read the document and update it without asking the user to authorize your app.

Issue Tracking mouse movement in Iframe

Details :-
In Our Project, we need to implement a functionality where we need to logout the user if he/she is inactive for 5 minutes. We need to consider user as inactive if he/she has not moved mouse for 5 mins.
We are able to achieve this in all normal pages but facing difficulties to implement in one page where we have an iframe in a page and that iframe plays videos and other swf, mp4 files. Also inside an iframe, there is another frame which acts as a wrapper for the content.
In above page, we are not able to track mouse movement and hence not able to detect whether user is active or not.
After lots of research, we have implemented code which works fine if we run through browser console but doesn't work when I keep this on page.
Has someone worked on similar functionality or know anything related to this? It would be great if someone can help me for this functionality.
Note :- Also there are click in Iframes
The iframe's source is technically speaking its own document (documentception?). The trick is to listen to the mouse events inside this document. Though I don't if this is allowed by the same origin policy, you could always give it a try.
Using plain JS:
var iframeDocument = document.querySelector('iframe').contentDocument;
iframeDocument.addEventListener('mousemove', function (event) {
console.log(event.pageX, event.pageY);
});
Using jQuery:
$('iframe').contents().mousemove(function(e) {
console.log(e.pageX, e.pageY);
});
You could go even further by dispatching all events made inside the iframe's document to the parent document. This gives you the advantage to use just one listener for all events, whether they come from inside the <iframe> or not.

Receiving touchmove events when scrolling a child iframe

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

Subscribe to javascript event in an iframe (facebook)

I have an application where I use an iframe for a facebook likebox.
I want to subscribe, in the main page, to the event when the user clicks on the like button in the iframe.
Basically as soon as the user likes the page I want him to be redirected to a page I'll specify.
What javascript command can I use?
Thanks
Unless your parent document is on the same domain as the Facebook Like frame, you can't script into it at all, for security reasons. This is the Same Origin Policy. It prevents you not only from detecting the click but also from impersonating the user, forcing them to perform actions (such as Liking you) without their consent.
You can try to place an element on top of the frame to detect clicks, but by intercepting the click you also stop it going through to the frame. About the best you can do is detect a hover over the area of the Like button and remove the covering element, allowing the user to click. This isn't reliable though since it'll catch all mouseovers.
You can hook this up to the button
onclick = "window.location('www.google.com')"
obviously replacing the URL with yours. But you might want to check if that's legal.

Categories

Resources