I am wondering what's the best solution for this. Return and show the nearest hyperlink on a webpage when the mouse is clicked.
There are 3 DIV
s in this example. each of them carries a hyperlink inside. There's also another hyperlink (hyperlink D) by itself without a DIV
. And lets say the red dot is mouse click.
For Example
The solution I can think of is just iterate through all the links by doing
var a_list = document.getElementsByTagName("a");
and then compute the distance by using distance equation c^2 = a^2 + b^2
, so simply
var a_list = Array.prototype.slice.call(document.getElementsByTagName("a"))
for( var i = 0 ; i < a_list.length; i++){
Math.sqrt(Math.pow(mouseX - a_list[i].getBoundingClientRect().left,2) +
Math.pow(mouseY - a_list[i].getBoundingClientRect().top,2))
}
This approach certainly takes about O(N) time complexity where N is the number of links that we have. Can we do better ?
This looks like a nearest neighbor
questions like you have a set S of n points in 2 dimensions, and a query point q. Which point in S is the closest one to q.
I think if you are dealing with not that many links (less than hundred links), then simple approach is the best (the one that you just have. Scan through each of them and calculate the distance, and take the minimal one), however if thousand or millions of links (barely happen) then you definitely need to cache it for later querying purposes, and that certainly speed up the time for querying.
One way (your way) is to get all the links and then sort them by X coordinate, you don't care about Y coordinate just for now, and then do a binary search on X, and you will end up with one of the link, but that may not be the closest one, you still need to compare with the previous one and the next one by distance (now use Y coordinate). For instance, From your example, when you do a binary search on X since the X coordinate of that red dotted (mouse clicked position) is greater than hyperlink D, so it will search everything after that, but hyperlink D could be the closest, so you need to take into consideration. This approach takes O(N log N) for sorting, O(N) space, and O(log N) for querying.
You can also use K-d Tree. It works pretty well with small number of dimensions (in your case it's only two dimensions x and y), and it can efficiently search for the cell containing the query point p (your mouse clicked position).
Construction time O(N log N), Space O(N) and Query Time: O(n^1/2 + k)
Another way I can think of is to construct the Voronoi diagram, which provide an efficient data structure for nearestneighbor queries and best for two dimension.
Construction time O(N log N), Space O(N) and Query Time: O(log n)
So pretty much all the approaches are the same.