使用角度js在contenteditable div上自动检测文本

时间:2014-06-12 05:54:53

标签: html angularjs angularjs-directive wysiwyg contenteditable

使用角度js的最佳方法是什么

contenteditable div 上撰写文字时,需要检测特殊字词,例如' {{FULL_NAME}}'并用预先定义的常量词隐藏标记

示例 - 如果有人写

'他的名字是{{FULL_NAME}}'

应立即转换为'他的名字是 john smith '

2 个答案:

答案 0 :(得分:1)

这是一个演示插件:http://plnkr.co/edit/GKYxXiDKv7fBeaE7rrZA?p=preview

服务:

app.factory('interpolator', function(){

  var dict = { .... };

  return function(str){
    return (str || "").replace(/\{\{([^\}]+)\}\}/g, function(all, match){
      return dict[match.trim().toLowerCase()] || all;
    });    
  };
});

指令:

app.directive('edit',[ 'interpolator', function(interpolator){
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {

      element.on('blur', function(e) {
        scope.$apply(function() {
          var content = interpolator(element.text());
          element.text(content);
          ngModel.$setViewValue(content);
        });
      });

      ngModel.$formatters.push(interpolator);

      ngModel.$render = function() {
        element.text(ngModel.$viewValue);
        ngModel.$setViewValue(ngModel.$viewValue);
      };
    }
  };
}]);

答案 1 :(得分:0)

这是一个使用简单DOM方法的示例,基于我在Stack Overflow上提供的其他答案。它还使用Rangy来保存和恢复选择,同时进行替换以使插入符不移动。

演示:

http://jsbin.com/zuvevocu/2

代码:

var editorEl = document.getElementById("editor");
var keyTimer = null, keyDelay = 100;

function createKeyword(matchedTextNode) {
    var el = document.createElement("b");
    el.style.backgroundColor = "yellow";
    el.style.padding = "2px";
    el.contentEditable = false;
    var matchedKeyword = matchedTextNode.data.slice(1, -1); // Remove the curly brackets
    matchedTextNode.data = (matchedKeyword.toLowerCase() == "name") ? "John Smith" : "REPLACEMENT FOR " + matchedKeyword;
    el.appendChild(matchedTextNode);
    return el;
}

function surroundInElement(el, regex, surrounderCreateFunc) {
    // script and style elements are left alone
    if (!/^(script|style)$/.test(el.tagName)) {
        var child = el.lastChild;
        while (child) {
            if (child.nodeType == 1) {
                surroundInElement(child, regex, surrounderCreateFunc);
            } else if (child.nodeType == 3) {
                surroundMatchingText(child, regex, surrounderCreateFunc);
            }
            child = child.previousSibling;
        }
    }
}

function surroundMatchingText(textNode, regex, surrounderCreateFunc) {
    var parent = textNode.parentNode;
    var result, surroundingNode, matchedTextNode, matchLength, matchedText;
    while ( textNode && (result = regex.exec(textNode.data)) ) {
        matchedTextNode = textNode.splitText(result.index);
        matchedText = result[0];
        matchLength = matchedText.length;
        textNode = (matchedTextNode.length > matchLength) ?
            matchedTextNode.splitText(matchLength) : null;
        surroundingNode = surrounderCreateFunc(matchedTextNode.cloneNode(true));
        parent.insertBefore(surroundingNode, matchedTextNode);
        parent.removeChild(matchedTextNode);
    }
}

function updateKeywords() {
    var savedSelection = rangy.saveSelection();
    surroundInElement(editorEl, /\{\w+\}/, createKeyword);
    rangy.restoreSelection(savedSelection);
}

function keyUpHandler() {
    if (keyTimer) {
        window.clearTimeout(keyTimer);
    }
    keyTimer = window.setTimeout(function() {
        updateKeywords();
        keyTimer = null;
    }, keyDelay);
}

editorEl.onkeyup = keyUpHandler;

相关: