根据给定坐标求离坐标最近的A元素

算法 guokai 发表于 9 年前最后回复来自 qq2850071112 7 年前

指定一个坐标,如 {left: 200, top: 300},如何获取离这个坐标最近的 a 标签?

共收到2条回复
guokai 9 年前 #1

常规解法(元素遍历):

closestToOffset: function(offset) {
    var el = null, elOffset, x = offset.left, y = offset.top, distance, dx, dy, minDistance;
    this.each(function() {
        elOffset = $(this).offset();

        if (
        (x >= elOffset.left)  && (x <= elOffset.right) &&
        (y >= elOffset.top)   && (y <= elOffset.bottom)
        ) {
            el = $(this);
            return false;
        }

        var offsets = [[elOffset.left, elOffset.top], [elOffset.right, elOffset.top], [elOffset.left, elOffset.bottom], [elOffset.right, elOffset.bottom]];
        for (off in offsets) {
            dx = offsets[off][0] - x;
            dy = offsets[off][1] - y;
            distance = Math.sqrt((dx*dx) + (dy*dy));
            if (minDistance === undefined || distance < minDistance) {
                minDistance = distance;
                el = $(this);
            }
        }
    });
    return el;
}
guokai 9 年前 #2

点扩散解法(抛砖引玉):

// 中心点向四周逐渐扩散的点集

var genPositions = function(curPos, distance, precision) {
    var posList = [];
    var step = distance * precision;

    if(distance === 0) {
        posList.push(curPos);
        return posList;
    }

    posList.push([curPos[0] - step, curPos[1] - step]);
    posList.push([curPos[0] + step, curPos[1] + step]);
    posList.push([curPos[0] + step, curPos[1] - step]);
    posList.push([curPos[0] - step, curPos[1] + step]);

    for(var i = (distance - 1) * -1 * precision; i <= (distance - 1) * precision; i += precision) {
        posList.push([i + curPos[0], curPos[1] - step]);
        posList.push([i + curPos[0], curPos[1] + step]);
        posList.push([curPos[0] - step, i + curPos[1]]);
        posList.push([curPos[0] + step, i + curPos[1]]);
    }

    return posList;
};

// 演示标出鼠标点击所在坐标周围最近的A元素

$(document).click(function(e) {
    var pos = [e.pageX, e.pageY];
    var tryList = [];
    var precision = 10; // 精度
    var distance = 1;
    var tryNode;
    var ret = [];

    // 周边A元素列表

    for(var i = 0; i < 1000; i++) {
        distance = i;
        tryList = genPositions(pos, distance, precision);

        for(var j = 0; j < tryList.length; j++) {
            tryNode = document.elementFromPoint(tryList[j][0], tryList[j][1]);

            if(tryNode && tryNode.nodeType === 1 && tryNode.nodeName === 'A') {
                ret.push(tryNode);
                //break;
            }
        }

        if(ret.length) {
            console.log('break');
            break;
        }
    }

    // 周边最近的A元素

    ret.sort(function(a, b) {
        var offset1 = $(a).offset();
        var offset2 = $(b).offset();
        var d1 = Math.pow(offset1.left - pos[0], 2) + Math.pow(offset1.top - pos[1], 2);
        var d2 = Math.pow(offset2.left - pos[0], 2) + Math.pow(offset2.top - pos[1], 2);

        return d1 - d2;
    });

    $(ret[0]).css('background-color', '#000');
});
登录后即可参与回复