如何计算DIV或P中的线框数量

时间:2012-06-23 09:27:43

标签: javascript dom caret

<div><span>aaaaaa</span> ... (many other span here) ... <span>zzzzzz</span></div>

在这种情况下,框跨度放在div内的几个线框上。 (span元素可以使用不同的字体大小。)

1)我们如何知道线框的数量?

2)我们能知道元素跨度放在哪个行框上吗?

3)我们能否知道插入符号的哪一行(符合条件)?

谢谢

2 个答案:

答案 0 :(得分:2)

我认为你的例子中的DOM是DOM实际复杂性的有效例子,而“line-boxe”只是一行文字。

1-2)对于<span>内的每个<div>,您可以使用以下内容计算他们跨越的行数:

var spans = div.getElementsByTagName("span"), spandata = [];
for (var i = 0; i < spans.length; i++) {
    var rects = spans[i].getClientRects();
    if (i > 0)
        if (rects[0].bottom > obj.rects[obj.rects - 1].bottom)
            var inirow = obj.lastRow + 1;
        else var inirow = obj.lastRow;
    var obj = {
        element: spans[i],
        rects: rects,
        iniRow: inirow,
        lastRow: inirow + rects.length - 1
    };
    spandata.push(obj);
}

现在spandata是您想要了解<span>元素的所有数据的列表。我还假设他们中的每一个都可以跨越多条线。

请注意,getClientRects在IE&lt; 8。

中存在一些问题

3)在现代浏览器中,getSelection方法可以帮助您:

var sel = window.getSelection();
if (sel.type === "Caret")
    var span = sel.anchorNode.parentNode;

关于线路位置,我必须说这不是一件容易的事。您无法轻易获得插入符号的页面位置。您可以做的最简单的事情是在插入符号的位置放置一个虚拟内联元素:

var text = sel.anchorNode.nodeValue;
sel.anchorNode.nodeValue = text.substring(0, sel.anchorOffset);
var dummy = document.createElement("i");
span.appendChild(dummy);
var pos = dummy.getBoundingClientRect();
sel.anchorNode.nodeValue = text;
span.removeChild(dummy);

pos包含插入符号位置的信息。现在你必须将它们与关于跨度的rect信息进行比较:

var rects = span.getClientRects();
for (var i = 0; i < rects.length; i++)
    if (rects[i]].bottom === pos.bottom) break;

if (i < rects.length) {
   for (var i = 0; i < spandata.length; i++) {
       if (spandata[i].element === span) {
           var line = spandata[i].iniRow + i;
           break;
       }
   }
}

最后,如果line != null,它包含插入符号的行。

男人,那很复杂......

答案 1 :(得分:1)

假设您的div位于el变量中:

el.children.length; // Number of direct children

// You have one of the children in the "child" variable, to know its index:
[].indexOf.call( el.children, child ); // Index of child in el.children

我没有提到那里的跨浏览器问题,但Array.prototype.indexOf仅在IE9启动时可用(因此它适用于所有现代浏览器)。