草庐IT

javascript - 寻找最近的 anchor href 滚动偏移量

coder 2024-05-13 原文

我有一个 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/

有关javascript - 寻找最近的 anchor href 滚动偏移量的更多相关文章

  1. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  2. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  3. ruby - 实现k最近邻需要哪些数据? - 2

    我目前有一个reddit克隆类型的网站。我正在尝试根据我的用户之前喜欢的帖子推荐帖子。看起来K最近邻或k均值是执行此操作的最佳方法。我似乎无法理解如何实际实现它。我看过一些数学公式(例如k表示维基百科页面),但它们对我来说并没有真正意义。有人可以推荐一些伪代码,或者可以查看的地方,以便我更好地了解如何执行此操作吗? 最佳答案 K最近邻(又名KNN)是一种分类算法。基本上,您采用包含N个项目的训练组并对它们进行分类。如何对它们进行分类完全取决于您的数据,以及您认为该数据的重要分类特征是什么。在您的示例中,这可能是帖子类别、谁发布了该项

  4. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  5. ruby-on-rails - 获取最近发生的星期三? - 2

    如何使用Ruby(和Rails,如果有相关的辅助方法)获取最近发生的星期三?最终需要实际日期(5/1/2013)。 最佳答案 time=Time.nowdays_to_go_back=(time.wday+4)%7last_wed=days_to_go_back.days.ago 关于ruby-on-rails-获取最近发生的星期三?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions

  6. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  7. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

    我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

  8. ruby - 使用 Selenium WebDriver 启用/禁用 javascript - 2

    出于某种原因,我必须为Firefox禁用javascript(手动,我们按照提到的步骤执行http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript)。使用Ruby的SeleniumWebDriver如何实现这一点? 最佳答案 是的,这是可能的。而是另一种方式。您首先需要查看链接Selenium::WebDriver::Firefox::Profile#[]=

  9. ruby - Watir-Webdriver 是否支持点击目标为 javascript 的链接? - 2

    我是Ruby和Watir-Webdriver的新手。我有一套用VBScript编写的站点自动化程序,我想将其转换为Ruby/Watir,因为我现在必须支持Firefox。我发现我真的很喜欢Ruby,而且我正在研究Watir,但我已经花了一周时间试图让Webdriver显示我的登录屏幕。该站点以带有“我同意”区域的“警告屏幕”开头。用户点击我同意并显示登录屏幕。我需要单击该区域以显示登录屏幕(这是同一页面,实际上是一个表单,只是隐藏了)。我整天都在用VBScript这样做:objExplorer.Document.GetElementsByTagName("area")(0).click

  10. ruby - 如何从二进制数据的偏移量开始读取? - 2

    我有一个类似C的结构:SomeStruct:lenVarsstring:namestring:lname#...end我在:Person之前有一堆偏移量和长度。所有偏移量和长度都描述了:Person结构中的数据。如何从指定的偏移量、给定的长度或直到下一个偏移量开始读取数据? 最佳答案 寻求偏移1234,然后将32个字节读入Strings:open'some-binary-file','r'do|f|f.seek1234s=f.read32#thoinyourcase,somethinglike:o=aBinData_object.r

随机推荐