可信的div不起作用

时间:2017-03-29 06:20:18

标签: javascript contenteditable

contenteditable无法正常工作,如果我们在句子之间写入文本。光标位置到句子的末尾。

var changed,
    lastValue = '',
    div = $('#ce'),
    words = ['oele', 'geel', 'politie', 'foo bar'];

function markWords() {
    var html = div.html().replace(/<\/?strong>/gi, ''),
        text = html.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' '),
        exp;
    $.each(words, function(i, word) {
        exp = new RegExp('\\b(' + word + ')\\b', 'gi');
        html = html.replace(exp, function(m) {
console.log('WORD MATCH:', m);
            return '<strong>' + m + '</strong>';
        });
    });
    //html = html.replace('&nbsp;', ' ').replace(/\s+/g, ' ');
console.log('HTML:', html);
console.log('----');
    div.html(html);
}

setInterval(function() {
    var html = div.html();
    if ( lastValue != html && html ) {
//console.log(lastValue);
//console.log(html);
//console.log('----');
        lastValue = html;
        markWords();
        setEndOfContenteditable(div[0]);
    }
}, 500);

function setEndOfContenteditable(contentEditableElement)
{
    var range,selection;
    if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
    {
        range = document.createRange();//Create a range (a range is a like the selection but invisible)
        range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
        selection = window.getSelection();//get the selection object (allows you to change selection)
        selection.removeAllRanges();//remove any selections already made
        selection.addRange(range);//make the range you have just created the visible selection
    }
    else if(document.selection)//IE 8 and lower
    { 
        range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
        range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
        range.select();//Select the range (make it the visible selection
    }
}
[contenteditable] {
    padding: 10px;
    border: dotted 1px #aaa;
}
[contenteditable] > div {
    margin: 10px 0;
}
[contenteditable] strong {
    font-weight: normal;
    background: red;
    color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ce" contenteditable>I love me some foo bar and shit.</div>

<p><a href="javascript:void(0);" onclick="$('#ce').html('');">clear</a></p>

1 个答案:

答案 0 :(得分:0)

编辑过的部分

  • 使用range.setStartrange.setEnd设置位置
  • callback function中的setInterval更改为单独的功能。
  • 使用setInterval代替setTimeout而不是一次调用该函数,然后从setEndOfContenteditable调用该函数。

var changed,
    lastValue = '',
    div = $('#ce'),
    words = ['oele', 'geel', 'politie', 'foo bar'];

function markWords() {
    var html = div.html().replace(/<\/?strong>/gi, ''),
        text = html.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' '),
        exp;
    $.each(words, function(i, word) {
        exp = new RegExp('\\b(' + word + ')\\b', 'gi');
        html = html.replace(exp, function(m) {
            return '<strong>' + m + '</strong>';
        });
    });
    setPos();
    div.html(html);
    setEndOfContenteditable(div[0]);
    console.log(pos);
}
function start() {
    var html = div.html();
    if ( lastValue != html && html ) {
        lastValue = html;
        setPos();
        markWords();
        setEndOfContenteditable(div[0]);
    }
}
setTimeout(start, 1000);
var pos=0;
function setPos(){
  if($(window.getSelection().anchorNode).is($(this))){
   	  pos=0;
  }else{
      pos=window.getSelection().anchorOffset;
 }
}
$("#ce").on('keyup',function(e){
       start();
    });
function setEndOfContenteditable(contentEditableElement)
{
    var range,selection;
    
    if(document.createRange)
    {
        range = document.createRange();
        range.selectNodeContents(contentEditableElement);
        range.setStart(contentEditableElement.firstChild, pos);
        range.setEnd(contentEditableElement.firstChild, pos);
        //range.collapse();
        selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    }
    start();
}
[contenteditable] {
    padding: 10px;
    border: dotted 1px #aaa;
}
[contenteditable] > div {
    margin: 10px 0;
}
[contenteditable] strong {
    font-weight: normal;
    background: red;
    color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ce" contenteditable>I love me some foo bar and shit.</div>

<p><a href="javascript:void(0);" onclick="$('#ce').html('');">clear</a></p>