我有一个 UIWebView
,其中的 HTML 页面已完全加载。 UIWebView
有一个 320 x 480 的框架并水平滚动。我可以获得用户当前所在的当前偏移量。我想使用 XY 偏移找到最近的 anchor ,这样我就可以“跳转到”那个 anchor 位置。这是可能吗?有人可以向我指出用于执行此操作的 Javascript 资源吗?
<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 ...
更新
我 super 伤心的JS代码:
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');
}
目标-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];
最佳答案
[更新] 我重写了代码以匹配所有具有 id 的 anchor ,并简化了我的 sortByDistance
函数中向量范数的比较。
检查我的尝试 on jsFiddle (上一个是 here )。
JavaScript 部分:
// findPos : courtesy of @ppk - see http://www.quirksmode.org/js/findpos.html
var findPos = function(obj) {
var curleft = 0,
curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft;
curtop = obj.offsetTop;
while ((obj = obj.offsetParent)) {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
}
}
return [curleft, curtop];
};
var findClosestAnchor = function (anchors) {
var sortByDistance = function(element1, element2) {
var pos1 = findPos( element1 ),
pos2 = findPos( element2 );
// vect1 & vect2 represent 2d vectors going from the top left extremity of each element to the point positionned at the scrolled offset of the window
var vect1 = [
window.scrollX - pos1[0],
window.scrollY - pos1[1]
],
vect2 = [
window.scrollX - pos2[0],
window.scrollY - pos2[1]
];
// we compare the length of the vectors using only the sum of their components squared
// no need to find the magnitude of each (this was inspired by Mageek’s answer)
var sqDist1 = vect1[0] * vect1[0] + vect1[1] * vect1[1],
sqDist2 = vect2[0] * vect2[0] + vect2[1] * vect2[1];
if ( sqDist1 < sqDist2 ) return -1;
else if ( sqDist1 > sqDist2 ) return 1;
else return 0;
};
// Convert the nodelist to an array, then returns the first item of the elements sorted by distance
return Array.prototype.slice.call( anchors ).sort( sortByDistance )[0];
};
当 dom 准备好时,您可以像这样检索和缓存 anchor :var anchors = document.body.querySelectorAll('a[id]');
我还没有在智能手机上测试过它,但我看不出有任何它不起作用的原因。
Here这就是我使用 var foo = function() {};
形式 ( more javascript patterns ) 的原因。
return Array.prototype.slice.call( anchors ).sort( sortByDistance )[0];
行实际上有点棘手。
document.body.querySelectorAll('a['id']')
返回一个 NodeList,其中包含当前页面正文中具有属性“id”的所有 anchor 。
遗憾的是,NodeList 对象没有“排序”方法,并且无法使用 Array 原型(prototype)的 sort
方法,as it is with some other methods, such as filter or map (NodeList.prototype.sort = Array.prototype.sort
会非常好)。
This article更好地解释了为什么我使用 Array.prototype.slice.call
将我的 NodeList 转换为数组。
最后,我使用 Array.prototype.sort
方法(以及自定义的 sortByDistance
函数)将 NodeList 的每个元素相互比较,然后我只返回最接近的第一项。
要查找使用固定定位的元素的位置,可以使用 findPos
的更新版本:http://www.greywyvern.com/?post=331 .
我的回答可能不是最有效的(drdigit 的肯定比我的更有效)但我更喜欢简单而不是效率,而且我认为它是最容易维护的。
[又一更新]
这是一个经过大量修改的 findPos 版本,适用于 webkit css 列(没有间隙):
// Also adapted from PPK - this guy is everywhere ! - check http://www.quirksmode.org/dom/getstyles.html
var getStyle = function(el,styleProp)
{
if (el.currentStyle)
var y = el.currentStyle[styleProp];
else if (window.getComputedStyle)
var y = document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
return y;
}
// findPos : original by @ppk - see http://www.quirksmode.org/js/findpos.html
// made recursive and transformed to returns the corect position when css columns are used
var findPos = function( obj, childCoords ) {
if ( typeof childCoords == 'undefined' ) {
childCoords = [0, 0];
}
var parentColumnWidth,
parentHeight;
var curleft, curtop;
if( obj.offsetParent && ( parentColumnWidth = parseInt( getStyle( obj.offsetParent, '-webkit-column-width' ) ) ) ) {
parentHeight = parseInt( getStyle( obj.offsetParent, 'height' ) );
curtop = obj.offsetTop;
column = Math.ceil( curtop / parentHeight );
curleft = ( ( column - 1 ) * parentColumnWidth ) + ( obj.offsetLeft % parentColumnWidth );
curtop %= parentHeight;
}
else {
curleft = obj.offsetLeft;
curtop = obj.offsetTop;
}
curleft += childCoords[0];
curtop += childCoords[1];
if( obj.offsetParent ) {
var coords = findPos( obj.offsetParent, [curleft, curtop] );
curleft = coords[0];
curtop = coords[1];
}
return [curleft, curtop];
}
关于javascript - 寻找最近的 anchor href 滚动偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10642587/