2011-11-21 61 views
1

如果一个HTML页面上的特定X-Y坐标垂直位于两行文本之间,那么如何使用Javascript(jQuery将起作用)说明?这些行可能在长段落的中间,在一个冗长的行项目标签内,跨度内,两个标签之间等等。我无法控制HTML或XY点,但我需要知道XY点位于一行文本的中间,或者位于两行文本之间;它需要非常高效。文本行之间是否存在特定的x-y坐标?

如果我还不够清楚,请回答您可能有的任何问题。

非常感谢。

+0

那么首先建议建立一个consitent基线网格,这将大大缓解您的计算。 Blueprintcss会给你这个开箱即用(960.gs不会),或者你可以创建自己的http://www.alistapart.com/articles/settingtypeontheweb – prodigitalson

回答

1

您可以在文本范围内调用.getBoundingClientRect()。您需要为IE和非IE浏览器编写单独的代码以获取文本范围。

在IE中这应该是相对容易的,这要归功于textRange.moveToPoint(x, y)。对于其他浏览器,您必须执行类似于DOM中元素的二进制搜索,在元素上调用.getBoundingClientRect(),直到找到包含文本的元素。然后创建一个包含该元素文本的范围,并对范围进行二分法搜索,以查找您的点是否与任何文本重叠。

如果你已经绝对定位了文本与其他元素重叠的元素,所有这些将会非常复杂。

+0

你可以利用[Rangy](http:// code。 google.com/p/rangy/),而不是为IE和非IE编写单独的代码:) – Kato

1

处理过文本范围后,我不认为你可以在技术上在同一个HTML节点上放置两行文本之间的任何内容。即使使用线条高度,每个像素也属于其中一条线条(即使它们之间有视觉空间)。

我会抛出一些可能有用的选项。

最简单的答案是可能只是使用线高度:(?event.relatedTarget jQuery中),这是点击 获取DOM元素 确定其偏移相对于页面(即如该元素的顶部) 确定被点击的点(x,鼠标事件Y的coords)使用 比较两个使用line-height of text行中

这将是这个样子:

function getLines(topOfElement, clickPoint, lineHeight) { 
    return Math.floor((clickPoint - topOfElement)/lineHeight); 
} 

var topOfElement = $(element).offset().top; //must be position: relative|absolute 
var clickedPoint = event.clientY; //might be pageY? 
var lineHeight = parseFloat($(element).css('line-height')); //probably need to set this in px using css or it might be null 
var textHeight = parseInt($(element).css('font-size')); //probably need to set this in px using css or it might be null 
var prevLineNumber = getLines(topOfElement, clickedPoint, lineHeight); 

// the previous line ends (in theory) at the bottom of the text (textHeight) 
// you might need to adjust this definition to your needs 
var prevLineBottom = prevLineNumber*lineHeight+topOfElement+textHeight; 

// the next line begins (in theory) at the top of its line 
// you might need to adjust this definition to your needs 
var nextLineTop = (prevLineNumber+1)+lineHeight; 

if(clickedPoint >= nextLineTop) { 
    alert('clicked on row '+(prevLineNumber+1)); 
} 
else if(clickedPoint <= prevLineBottom) { 
    alert('clicked on row '+prevLineNumber); 
} 
else { 
    alert('clicked between rows '+prevLineNumber+' and '+(prevLineNumber+1)); 
} 

如果你想看看点击哈在两个html节点之间,你可以用Rangy来做到这一点,以及一些奇特的选择和范围计算。

您可以将它用于确定选择前后文本的确切长度等内容。这只有在你想看到他们点击的文本中的哪个位置时才有用。

function getTextAtClick() { 
    var result = {nodeClicked: null, textBefore: '', textAfter: '', valid: false}; 

    //get a selection object (even though the selection is technically zero length) 
    var sel = rangy.getSelection(); 

    //you would probably want to discard any selection not zero length (i.e actual selection of text instead of a click) 
    // if not, you'd need to decide what it means to select across multiple dom nodes :(
    if(sel.toString().length > 0) { return result; } 

    // get the point where the click occurred 
    var range = sel.getRangeAt(0); 
    result.valid = true; 

    // determine text in our dom element up to the click point 
    var before = rangy.createRange(); 
    before.setStart(range.startContainer, 0); 
    before.setEnd(range.startContainer, range.startOffset); 
    result.textBefore = before.toString(); 

    // determine text in our dom element after the click point 
    var after = rangy.createRange(); 
    after.setStart(range.startContainer, range.startOffset+1); 
    after.setEndAfter(range.startContainer); 
    result.textAfter = after.toString(); 

    return result; 
}