http://classjs.com/2013/03/05/js%E8%8E%B7%E5%8F%96%E7%B2%98%E8%B4%B4%E5%86%85%E5%AE%B9/

思路:在编辑环境中,粘贴时先记录光标在编辑器中的位置,再创建一个空的div,并且设置为可编辑的(contenteditable=”true”),让光标聚焦其中,聚焦的技巧是div.focus(),此时光标粘贴操作是在刚才新创建的那个div里,那内容自然也就在该div里,利用setTimeout取到div的内容,最后重新定位光标到粘贴前位置并插入内容。

哈哈,这种思路挺讨巧的,不过其中的技巧并不是那么容易发现的。比如div.focus和setTimeout的技巧,但是我试了下,在iframe模式下是无效的,被卡在了focus那一步,因为iframe下的body是一个contenteditable=”true”环境,即focus状态,它的子元素也是处于这样一种状态,所以没法再次focus();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
onBeforePaste: function(target, e)
    {
        // ie浏览器下,如果选中了文字,则不执行粘贴前处理;保证鼠标右键的正确行为。
        if (__BROWSER.msie)
        {
            var range = document.selection.createRange();
            if (range.text.length >0)
            {
                return true;
            }
        }
         
        var self = this;
         
        // 记住容器滚动条位置
        target.style.position = "static";
        this.saveScrollTop();
         
        // 光标占位
        var caretHolder = __addCaretHolder(target);
        var tmpDiv = document.createElement("div");
        tmpDiv.contentEditable = true;
        tmpDiv.style.position = "absolute";
        tmpDiv.style.top = caretHolder.offsetTop + "px";
        tmpDiv.style.left = caretHolder.offsetLeft + "px";
        tmpDiv.style.width = "1px";
        tmpDiv.style.height = "1px";
        tmpDiv.style.overflow = "hidden";
        this.container.appendChild(tmpDiv);
        tmpDiv.focus();
        // 执行粘贴操作
        __setTimeoutEx(0, function(){
            var txt = tmpDiv.innerHTML;
           
            caretHolder.innerHTML = txt;
            __setCaret(caretHolder, -1);
            __removeCaretHolder();
            if (tmpDiv.parentNode)
            {
                tmpDiv.parentNode.removeChild(tmpDiv);
            }
             
            // 粘贴时容器的滚动条会自动滚动,此处需要复原
            target.style.position = "relative";
            self.restoreScrollTop();   
        });
         
        return true;
    },
05-23 00:54