I'm building a Facebook app. Facebook canvas type is FBML, then I put the fb:iframe inside the index page, load my ajax engine inside of that iframe, and after that, all content is updated trhough ajax. Sometimes the content pages can be long and requre the user to scroll down (with the main browser scrollbar). But when you click a link after scrolling down and the next content page is loaded, the scrollbar remains where it was (which makes sense), so you have to scroll back to the top.
I managed to solve this by forcing a scroll after the data is loaded. And it does get to the top of the div, but not to the top of the page, where the facebook bar is. I tried scrolling the parent window but thats not possible due to cross-site security restrictions.
I noticed that when you use the FB.ui (ie. to create a stream to publish) from within the same place where I load my content, it does scroll all the way to the top. So I guess maybe there's a FB api call to do that, but I cant find it.
Or maybe some way to force the browser to scroll all the way up no matter if you're at an iframe?
Any ideas?
UPDATE April 2011:
Facebook added the FB.CanvasClient.scrollTo method to their new JavaScript SDK. All you have to do now is:
FB.Canvas.scrollTo(0,0);
More info here: http://developers.facebook.com/docs/reference/javascript/FB.Canvas.scrollTo/
UPDATE April 2011: The following content is now outdated, but I'm leaving it here for reference purposes...
Are you using the new JavaScript SDK or the old one? With the old one, you can do this:
FB.CanvasClient.scrollTo(0,0)
Unfortunately, Facebook doesn't support the scrollTo() method with the new JavaScript API. I haven't tried this next technique with an FBML app, but I did have success with it using it in a Canvas iframe app (code borrowed from here: http://forum.developers.facebook.net/viewtopic.php?id=32906):
var x = 0, y = 0;
$("body").append('<iframe id="scrollTop" style="border:none;width:1px;height:1px;position:absolute;top:-10000px;left:-100px;" src="http://static.ak.facebook.com/xd_receiver_v0.4.php?r=1#%7B%22id%22%3A0%2C%22sc%22%3Anull%2C%22sf%22%3A%22%22%2C%22sr%22%3A2%2C%22h%22%3A%22iframeOuterServer%22%2C%22sid%22%3A%220.957%22%2C%22t%22%3A0%7D%5B0%2C%22iframeInnerClient%22%2C%22scrollTo%22%2C%7B%22x%22%3A' + x + '%2C%22y%22%3A' + y + '%7D%2Cfalse%5D" onload="$(\'#scrollTop\').remove();"></iframe>');
While the above technique will scroll the window to the top, I didn't find it 100% reliable. For example, it doesn't seem to work in Facebook's new Page iframe tabs. So I've resorted to using this 100% reliable technique, but unfortunately, it will only scroll to the top of the iframe:
Place this just below your opening tag:
<a id="top" name="top" style="display:block;height:1px;width:1px;"></a>
And the JavaScript that will do the scrolling;
window.location.hash = 'top';
window.location.hash = '';
Related
I have been tasked with building a SPA that has some complex page transitions.
My biggest concern is that these transitions rely on elements expanding on the page to then become the full page (i.e. you click a blue button, the blue background expands to fill the whole page and then the content is displayed.)
Now this is where I am struggling to come up with an accessible solution. I thought about making the text within the original 'button' a link with padding (as the URL will update and the link is for no JavaScript fallback) and then replacing the content of the parent div (the blue background) with the new content.
The problem I have is that I am not sure what would be the best practice for accessibility from the perspective of letting a screen reader user know that a new page has loaded in. Using aria-live is a terrible idea, but with NVDA if I just replace the contents of the div it can have some strange behaviour.
Has anyone ever come across this before? For example this dribble nearly shows what I mean, you click an element and then it opens up into a new page with the content within the element.
For a 'normal' AJAX site when navigating I would simply replace the whole <main> with the new content, make the <h1> programatically focused with a tabindex="-1", update the page <title> and that works fine, but with this type of navigation I am wondering if the same approach is applicable.
I am thinking replacing everything within the <main> element except for the selected 'button' background (including the original link being removed once the new page has loaded) and then loading the content in and managing the focus as described would work, but I am not sure if there is an accepted pattern for this type of navigation as it is so unusual.
I am thinking replacing everything within the element except
for the selected 'button' background (including the original link
being removed once the new page has loaded) and then loading the
content in and managing the focus as described would work, but I am
not sure if there is an accepted pattern for this type of navigation
as it is so unusual
I think this is your best best. The whole visual expanding thing is just eye candy, so as long as it is there you should be able to do this behind the scenes. Make sure you test with screen readers.
I know in Xamarin we can use Tabbed page, Carousel page... but I wonder that if I open every new page like this:
Application.Current.MainPage = new MyPage();
Is this a bad approach? Is this effect performance or any other things?
Basically when you use PushAsync, it adds the new page on top of the navigation stack. The navigation stack is a LIFO you can manage using PushAsync, PopAsync or the back button. So when you use PopAsync, it removes the last page from the stack (as it does using the back button).
Using Application.Current.MainPage = new MyPage(); for opening every page, you are just overriding the very first element of the stack and therefore you are not able to use back navigation at all since you would always keep one single page into the navigation stack.
Moreover, with this approach, clicking on the back button will exit the app.
You can do this as long as it works for you. However it may cause some problems, especially that you can't use the system back function in any way. Also you may lose some animations that should be part of the standard UI and that are considered as a good practice.
With the recent Firefox and Chrome browser releases, the default status bar has been taken from us to free up more screen space and de-clutter the UI. The status bar was used to display the URL of any link the user rolls over, among other things.
The browser makers couldn't completely remove the status part of the status bar, because users need to be shown where they will be going if they roll over a link. They've settled into displaying a temporary, tooltip-style modeless text bar that appears at the bottom left or right of the browser window's client area on link rollover.
I'll put aside my displeasure with the browser makers invading MY beautiful client area and smearing their chrome all over with distracting fade-in transitions and weak color/contrast choices. I'd just like some suggestions on how to best deal with this current situation.
I use absolute positioning to keep some of my DOM elements in the lower left and right of the visible client area on the page. Is there a way to detect in javascript how tall these temporary status bars will be so that I can vertically offset my elements far enough from the bottom of the page so that they are not occluded by the temporary status bar?
Browser plugins like StatusBar-4-Evar are not a good solution for me because I could never suggest that my users install anything to view my website. I'd like solutions to work with the browsers' default settings.
I don't want to work too hard for this; I'd like to avoid browser/version detection to know when I should vertically offset my elements. I am ready to accept if my page design is not workable and to assume the bottom of the page is now off-limits to any content other than that page content which flows there naturally.
I want to persist the user's location in the document he or she is browsing, then bring them back to that spot when they return from tombstoning or between sessions.
My first approach was to wrap the browser component in a scrollviewer, but it turns out it handles its own scrolling and the scrollviewer never changes its verticaloffset.
My guess is that the browser component must have a scrollviewer or something like it embedded in it. I need to get the verticaloffset and scroll to an offset.
Any guesses how to get there?
My next approach would be a painful mish-mash of javascript and c# to figure out where they are...
Because of the way the WebBrowser control is built you'll need to track scrolling in Javascript then pass the location to managed code to handle storage of that value.
On resuming you'll need to have the managed code pass the scroll position to a Javascript function to reset the scroll position.
That's the theory but I haven't looked at the funcitonality around javascript scrolling events in the WebBrowser yet. That's the only place I can see possible problems.
Would be good to hear how you get on.
I've accepted Matt's answer, but I want to put in some details here. I'm also going to blog about how I did it once I'm completely done.
Since the WebBrowser component is essentially a black-box, you don't have as much control as I would like. Having said that, it is possible to get and set the vertical offset.
Javascript lets you ask for the value, but different browsers use different variations on HOW to ask. For THIS case I only have one browser to worry about.
First I make a couple of simple javascript functions:
function getVerticalOffset() {
return document.body.scrollTop;
}
function setVerticalOffset(offset) {
document.body.scrollTop = offset;
}
Next I call into the WebBrowser using the InvokeScript method on the browser object.
I'll post an update here with a link to my blog when I get the full write-up done.
I have been writing an eBook reader and had a similar question. Code for setting a scroll position has been easy enough to find.
Code for setting vertical scroll position:
string script = string.Format("window.scrollBy(0,{0});", "put your numeric value here");
wb_view.InvokeScript("eval", script);
Google didn't help much in finding solution for getting the value of current scroll position. Lacking any knowledge in javascript it took me almost two hours to get it right.
Code for getting the vertical scroll position:
var vScroll = wb_view.InvokeScript("eval",
"var vscroll = window.pageYOffset; vscroll.toString();");
i am using code right out of the examples in yahoo maps api, but when i click on a smart window i get the close button (x) in the upper left. the only thing i am changing is the html in the smart window but i dont understand why that would affect the location of the close button. also, i dont see any documentation on how to change this on the yahoo maps api web site.
You may want to look in your page CSS for anything that floats img tags left or positions them absolutely (think along those lines).
One debugging method would be to temporarily turn off your page's CSS to see the result.