使用keypress创建contenteditable标签

时间:2018-01-01 23:52:42

标签: javascript contenteditable

编辑:以下代码仅适用于Chrome / Opera

我修改了找到here的代码,使用keypress事件在contenteditable中创建主题标签。基本上,只要有人键入散列(#)符号,就会立即创建span标记(通过Bootstrap和其他css设置样式),并在每次按下空格或任何标点符号时关闭。这就是它的长短。

这是我的代码:

function placeCaretAtEnd(el) {
  el.focus();
  if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
    var range = document.createRange();
    range.selectNodeContents(el);
    range.collapse(false);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
  } else if (typeof document.body.createTextRange != "undefined") {
    var textRange = document.body.createTextRange();
    textRange.moveToElementText(el);
    textRange.collapse(false);
    textRange.select();
  }
}

// closes the span housing the hashtag
function closeSpan(){
  var span = document.createElement("span");
  span.setAttribute("data-role", "remove");
  span.setAttribute("class", "delHashtag");
  span.setAttribute("aria-hidden", "true");
	return span;
}

$(document).ready(function() {
	var hashtags = false;
  
  $(document).on('keypress', '#myInputField', function(e) {
    var input_field = $(this);
    var x = e.which || e.keyCode;
    if (x == 32){ // space key
      if(hashtags){
        e.preventDefault();
        input_field.html(input_field.html() + "</span>&nbsp;");
        placeCaretAtEnd(this);
        hashtags = false;
        document.getElementsByClassName("new")[0].setAttribute("contenteditable", false);
  			document.getElementsByClassName("new")[0].appendChild(closeSpan());
      }
    }
    if (x == 35){ // hash key (#)
      e.preventDefault();
      $(".tag").removeClass("new");
      input_field.html(input_field.html() + "<span class='tag label label-info new'>#");
      placeCaretAtEnd(this);
      hashtags = true;
    }
    // various punctuation characters
    if (x == 8 || x == 9 || x >=16 && x <= 18 || x == 27 || x == 33 || x == 34 || x >= 36 && x <= 47 || x >= 58 && x <= 64 || x >= 91 && x <= 94 || x == 96 || x >= 123 && x <= 126) {
      if(hashtags) {
        e.preventDefault();
        input_field.html(input_field.html() + "</span>" + String.fromCharCode(x));
        placeCaretAtEnd(this);
        hashtags = false;
        document.getElementsByClassName("new")[0].setAttribute("contenteditable", false);
  			document.getElementsByClassName("new")[0].appendChild(closeSpan());        
      }
    }
    if(x == 13){// return key
      document.execCommand('defaultParagraphSeparator', false, 'p');
    }
    
  });
  
  $(document).on("click", ".delHashtag", function() {
    this.parentNode.parentNode.removeChild(this.parentNode);
    return false;
  });
  
});
#myInputField {
  border:1px solid #ddd;
  padding: 10px;
  font-size: 14px;
}

.tag span[data-role="remove"] {
  margin-left: 8px;
  cursor: pointer;
}

.tag span[data-role="remove"]:after {
  content: "x";
  padding: 0px 2px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div id="myInputField" contenteditable="true"></div>

按预期创建Hashtags。但是,如果单击文本中的其他位置并尝试创建主题标签,则不会在光标所在的位置创建主题标签。相反,主题标签到达了contenteditable的末尾。不好。

我无法弄清楚这一点。当然,代码还有其他问题(即没有验证hashtags;按下return后创建的第一个hashtag出现在另一行(不会保留在p / div标签内)),但我现在专注于这一个问题

Javascript忍者可以帮我一把吗?我真的很感激。

0 个答案:

没有答案