I have a UIWebView with an HTML page completely loaded. The UIWebView has a frame of 320 x 480 and scrolls horizontally. I can get the current offset a user is currently at. I would like to find the closest anchor using the XY offset so I can “jump to” that anchors position. Is this at all possible? Can someone point me to a resource in Javascript for doing this?
<a id="p-1">Text Text Text Text Text Text Text Text Text<a id="p-2">Text Text Text Text Text Text Text Text Text ...
Update
My super sad JS code:
function posForElement(e)
{
var totalOffsetY = 0;
do
{
totalOffsetY += e.offsetTop;
} while(e = e.offsetParent)
return totalOffsetY;
}
function getClosestAnchor(locationX, locationY)
{
var a = document.getElementsByTagName('a');
var currentAnchor;
for (var idx = 0; idx < a.length; ++idx)
{
if(a[idx].getAttribute('id') && a[idx+1])
{
if(posForElement(a[idx]) <= locationX && locationX <= posForElement(a[idx+1]))
{
currentAnchor = a[idx];
break;
}
else
{
currentAnchor = a[0];
}
}
}
return currentAnchor.getAttribute('id');
}
Objective-C
float pageOffset = 320.0f;
NSString *path = [[NSBundle mainBundle] pathForResource:@"GetAnchorPos" ofType:@"js"];
NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[webView stringByEvaluatingJavaScriptFromString:jsCode];
NSString *execute = [NSString stringWithFormat:@"getClosestAnchor('%f', '0')", pageOffset];
NSString *anchorID = [webView stringByEvaluatingJavaScriptFromString:execute];
[UPDATE] I rewrote the code to match all the anchors that have an id, and simplified the comparison of the norm of the vectors in my
sortByDistancefunction.Check my attempt on jsFiddle (the previous one was here ).
The javascript part :
You can retrieve and cache the anchors like so when the dom is ready :
var anchors = document.body.querySelectorAll('a[id]');I’ve not tested it on a smartphone yet but I don’t see any reasons why it wouldn’t work.
Here is why I used the
var foo = function() {};form (more javascript patterns).The
return Array.prototype.slice.call( anchors ).sort( sortByDistance )[0];line is actually a bit tricky.document.body.querySelectorAll('a['id']')returns me a NodeList with all the anchors that have the attribute “id” in the body of the current page.Sadly, a NodeList object does not have a “sort” method, and it is not possible to use the
sortmethod of the Array prototype, as it is with some other methods, such as filter or map (NodeList.prototype.sort = Array.prototype.sortwould have been really nice).This article explains better that I could why I used
Array.prototype.slice.callto turn my NodeList into an array.And finally, I used the
Array.prototype.sortmethod (along with a customsortByDistancefunction) to compare each element of the NodeList with each other, and I only return the first item, which is the closest one.To find the position of the elements that use fixed positionning, it is possible to use this updated version of
findPos: http://www.greywyvern.com/?post=331.My answer may not be the more efficient (drdigit’s must be more than mine) but I preferred simplicity over efficiency, and I think it’s the easiest one to maintain.
[YET ANOTHER UPDATE]
Here is a heavily modified version of findPos that works with webkit css columns (with no gaps):