在内容可编辑div中的新行上触发事件

Dav*_*ton 24 html css jquery contenteditable angularjs

我正在尝试侦听一个事件,该事件表明已在内容可编辑div中创建了新行.目的是最终在每次创建新的空行并且插入符号位于该行上时,或者如果用户将插入符号位置单击到当前空行时,向用户显示一些选项.

在我的书中,似乎有四个事件会导致用户在一个可信的div中处于新的界限:

  • 按进入
  • 粘贴最后有空行的内容
  • clicking causing the caret (blinking line) to move position to an empty line
  • using the arrow keys to move to a new line

Of course in a contentediable div a new line means different things to different browsers, in chrome it seems to create <div><br/></div> tags, but having browsed around SO enough it seems that other browsers might create <div><p></p></div> or perhaps <span> tags.

I've now tried to figure this out a couple of times and just have to get it done. Is it really the best way to listen for new elements being added under that div, and/or check if the caret position is currently within empty 'new line' tags. checking each time the caret moves seems highly inefficient - is there a better way to do this?

To summarise for tldr; people

  • is there a better way to check for new lines in content editable divs?
  • how would I trigger an event based upon that efficiently?

Just fyi this is within an Angular context and I have jQuery also (the answer can choose to use or not use these libraries).

----- edit -----

So far the answers have focused on the creation of new line 'events' and monitoring those events, perhaps polling the caret position is a more reliable way to determine if the caret is on a empty line or not.

Dav*_*ton 11

到目前为止,其他答案讨论了监视在内容可编辑div中创建换行符的事件.然而,从迄今为止的努力来看,这似乎不是监视用户是否已将插入符号放在新行上的可靠方式.

尽管担心setInterval事件变得笨拙并且增加了开销,但这可能只是我的看法.我在OSX上测试了Firefox和Chrome中的以下内容.

function getNewLines() {
  console.log(document.getSelection());
  if (document.getSelection().anchorNode) {
    var node = document.getSelection().anchorNode;
    var nodeContents = "";
    if (node.innerHTML) {
      nodeContents = node.innerHTML.toLowerCase();
    } else {
      nodeContents = node.innerHTML;
    }
    if (nodeContents !== undefined) {
      if (nodeContents === "" || nodeContents == "<br>" || nodeContents ==
        "<br/>" || nodeContents.substr(nodeContents.length - 5) == "<br/>" ||
        nodeContents.substr(nodeContents.length - 4) == "<br>") {
        console.log("you are on a new line :]");
      } else {
        console.log('nope not a new line');
      }
    } else {
      console.log('nice try, but no not a new line');
    }
  }
}
setInterval(getNewLines, 100);
Run Code Online (Sandbox Code Playgroud)
<div contenteditable="true">
  <p>Lets get started!</p>
</div>
Run Code Online (Sandbox Code Playgroud)

见小提琴

侧注:内容可编辑的换行符似乎有所不同,但我在firefox中注意到它将模仿该字段中的现有元素.即如果你使用<div></div>,firefox将使用<div></div>,如果你使用<p></p>Firefox将会做同样的事情


Ahs*_*s N 9

这就是我做的:

$("#main").keyup(function (e) {
    if (e.which == 13) {
        doSomething();
    }
});
$("#main").on("click", "div:has(br)", function () {
    doSomething();
});
$("#main").on("paste", function () {
    setTimeout(function () {
        debugger;
        if ($('#main').children().last().children().last().has('br').length >0) {
            doSomething();
        }
    }, 100);
});

function doSomething(){
   alert("new line...");
}
Run Code Online (Sandbox Code Playgroud)

这是JSFiddle演示