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

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

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

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

3)我们可以知道插入符号放置在哪个行框上(内容可编辑)?

谢谢

4

2 回答 2

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<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,它包含插入符号的行。

人,这很复杂……

于 2012-06-23T10:03:48.627 回答
1

假设您divel变量中:

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 开始使用(因此它适用于所有现代浏览器)。

于 2012-06-23T10:00:42.250 回答