baker
baker copied to clipboard
Horizontal Anchor Links
Hi - I'm attempting to do something like enable your item "1" in your list of 5 items regarding your new anchor link implementation (thank you - this is a great feature!) on this page: https://github.com/Simbul/baker/issues/64:
1. Links from a page of the book to a page of the book with anchor, goes there correctly.
Without this capability, I am not able to have the page and book behavior I'm looking for, which is:
a) Tap an anchor link from a TOC page to go to a horizontal anchor in the destination page.
b) Have this destination page reside in the book.json manifest.
I am able to of course get the horizontal anchor to work in a page not included in the book.json list, since this forces the book app to open this page in a UIWebView, which obeys horizontal anchor links. However, what this means is that this new page basically replaces my TOC page, and thus will swipe left and right to the pages consecutively before / after the TOC page - not its own pages since it doesn't exist in the book.json chronology.
It would be great to be able to horizontally anchor on a page and still have this page swipe left or right to its own consecutive pages.
I tried to create a goRightInPage pragma mark, and use this to modify the handleAnchor mark (all based on the implementation you have for vertical anchor links) but this didn't work - it looks like its the case that that vertical anchor links also call up the webview.
Perhaps another approach / workaround is a possibility, for example, it would be ok to have the webview if upon click, a destination URL like "somepage.html#anchor1" first went to "somepage.html" and THEN loaded in "somepage.html#anchor1".
Any suggestions?
I'm not sure what you are trying to achieve. I can guess that "horizontal anchor" is a normal link to another page since that was the reference of the point (1) in the Issue #64.
Could you:
- Tell us what Baker version are you using.
- Test if it works in the latest 3.2 from the website, the current MASTER from here and, just in case, version 3.0?
- Paste here the link you are using, and maybe a step-by-step description of what happens and what should happen instead.
Thanks. :)
Thanks for replying. In a nutshell - this is all for the sake of being able to link to the right-hand side of pages of my book. in the process, I'm sharing the bit of orientation support for magazine pages that I've come up with, see the link below.
- I am using Baker 3.2.
- I tried my code (not Xcode, just HTML / CSS / Javascript in the /book file) on a fresh download of 3.2 from the latest master on git as you suggested.
- Here are some sample files from the orientation support / horizontal anchor link feature I made for a book I'm working on: https://github.com/CatherineEng/Orientation-Support-for-Books
Below are some steps to view my orientation support feature. Before I get into those let me explain how I got here.
Basically, I want my book to display a left page and right page in landscape mode, then only a left or right page in portrait mode, as most ebooks and magazines do.
To make a nice transition on orientation switch from portrait to landscape, I wrote a simple bit of CSS in a media query. This works great. No weird flashes / pauses on orientation, just nearly instantaneous CSS transition. You can see what I've done by looking at media-queries.css and looking at the container classes in the file destination.html.
In other words, the spreads in my book are each a single .html file, with facing left and right page "containers".
The problem is when I try to access the right page container in one of these .html files in portrait mode from another page of the book. It defaults to the left container, since it is on the top left, (0,0) of the destination page.
I tried a few things in the Baker Xcode, like created a goRightInPage variable in the Page Scrolling pragma similar to goUpInPage and goDownInPage, but thought I might be able to do things more simply after all with javascript.
So here are my experiments so far. To view them, please open up origin.html in a browser (adjust window width to 768px wide) or add it to your book.json file and view in portrait mode in the iOS simulator:
- Click Link A: Goes straight to right-hand container! I can get a direct jump to the right-page container if I add a <body onload> event in the destination file itself but this isn't ideal, because sometimes I will want the page to land on the left container. (See "A" in the origin.html file) I use a window.scroll event to a coordinate to do this, not an anchor link because of that webview issue for anchor links in Baker (This actually worked... in the sense that the origin file a href anchor link jumped to the right-page container. However, since it IS an anchor link, and Baker calls anchor links in a webview, the destination page appears in a webview. The only problem with this, is that then the page actually drops on top of the orientation page so the previous / next pages are that of the origin page, not the destination page, which would be confusing to readers). In any case, this proves that it's possible to jump to a right-page from a link from another page.
- Click Link B: Will land on the left-hand container, but click to the right-page container! Once I am on the destination page, viewing the left-page container, I can click a link to anchor to the right-hand page. This proves horizontal anchor links do work.
- Click Link C: Lands on the left-hand container, and that's about it. The problem arises when I try to have the origin page jump to the right-hand container of the destination page with a conditional script. A variable passed from the origin page in the URI causes some iteration - the application has to decide how to handle this unusual link and tries to open it as a webview, decides it doesn't need to, and by then, just deposits you on the default left container of the page, forgetting all about the anchor or scroll script / detect.
So... if you could help point me in the right direction of how to write some variable into the origin link, that could be passed to the destination page so the destination page will obey either a straight anchor link (some modifications to Xcode necessary) or a javascript function to scroll or anchor to the right container, that would be great.
Ok, I checked it. We have a quite complex code inside Baker to manage urls, so it's going to be complicated to find a solution there.
The best workaround I can suggest you is to use localStorage
, in this way:
in destinationAnchor.html
:
<script type="text/javascript">
function jumpScroll()
{
if (window.localStorage.side == 'right') {
window.scroll(770,0); // horizontal and vertical scroll targets
window.localStorage.side = '';
}
}
</script>
in origin.html
:
<script>
function jumpToPage(url, side) {
window.localStorage.side = side;
window.location = url;
}
</script>
<li>LINK C: <a onclick="jumpToPage('destinationAnchor.html', 'right')">Click here to try to make destination page anchor right </a></li>
It's not as clean as it should be, but should work. Let me know. :)
Hi @CatherineEng did it work?
Hi, thank you so much Folletto for your response. I did try it, but as my pages have so much javascript already, and almost every page needs this right-page target feature, I had some help from the fabulous @mmackh who added this to the page scrolling pragma in RootViewController.m, line 1512 (but after the goUpInPage and goDownInPage statements):
- (void)scrollPage:(UIWebView *)webView to:(NSString *)offset animating:(BOOL)animating {
[self hideStatusBar];
NSString *jsCommand;
if (pageWidth == [offset integerValue])
{
jsCommand = [NSString stringWithFormat:@"window.scrollTo(%@,0);", offset];
}
else
{
jsCommand = [NSString stringWithFormat:@"window.scrollTo(0,%@);", offset];
}
if (animating) {
[UIView animateWithDuration:0.35 animations:^{ [webView stringByEvaluatingJavaScriptFromString:jsCommand]; }];
} else {
[webView stringByEvaluatingJavaScriptFromString:jsCommand];
}
}
- (void)handleAnchor:(BOOL)animating {
if (anchorFromURL != nil) {
if ([anchorFromURL isEqualToString:@"menuanchor"])
{
NSString *offset = [NSString stringWithFormat:@"%d", pageWidth];
if(!UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
[self scrollPage:currPage to:offset animating:animating];
}
anchorFromURL = nil;
}
else
{
NSString *jsAnchorHandler = [NSString stringWithFormat:@"(function() {\
var target = '%@';\
var elem = document.getElementById(target);\
if (!elem) elem = document.getElementsByName(target)[0];\
return elem.offsetTop;\
})();", anchorFromURL];
NSString *offset = [currPage stringByEvaluatingJavaScriptFromString:jsAnchorHandler];
if (![offset isEqualToString:@""]) {
[self goDownInPage:offset animating:animating];
}
anchorFromURL = nil;
}
}
}
And then any time you want to target a right-hand page, include #menuanchor in your link i.e. <a href="http://yourlink.com#menuanchor">
Works like a charm. :-)