如何在angularjs中包装文本并保存位置

时间:2014-10-04 11:51:55

标签: angularjs

我想用span标签包装文本并保存位置。 我知道怎么用JS做,但我不知道怎么用angularjs

这就是我所做的:

http://jsfiddle.net/ymeaL06j/1/

此功能为我提供了DIV中文本的位置

function getSelectionPosition() {
  var range = window.getSelection().getRangeAt(0);
  var preSelectionRange = range.cloneRange();
  preSelectionRange.selectNodeContents(document.getElementById("code"));
  preSelectionRange.setEnd(range.startContainer, range.startOffset);
  var start = preSelectionRange.toString().length;

  return {
    start: start,
    end: start + range.toString().length
  }
};

我选择开始和结束位置并将它们作为属性插入span标记

在此之后我想保存所有标记的位置并稍后加载它,我有一个选择文本的功能然后我可以包装它(我希望有更好的解决方案)

function setSelection(savedSel) {
  var charIndex = 0, range = document.createRange();
  range.setStart(document.getElementById("code"), 0);
  range.collapse(true);
  var nodeStack = [containerEl], node, foundStart = false, stop = false;

  while (!stop && (node = nodeStack.pop())) {
      if (node.nodeType == 3) {
          var nextCharIndex = charIndex + node.length;
          if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
              range.setStart(node, savedSel.start - charIndex);
              foundStart = true;
          }
          if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
              range.setEnd(node, savedSel.end - charIndex);
              stop = true;
          }
          charIndex = nextCharIndex;
      } else {
          var i = node.childNodes.length;
          while (i--) {
              nodeStack.push(node.childNodes[i]);
          }
      }
  }

  var sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
}

1 个答案:

答案 0 :(得分:1)

您可以使用上面说明的相同代码并将其放在angularjs控制器中。

请参阅my plunker code;它是你的jsfiddle代码的简单angularjs版本。

例如,假设index.html的片段如下所示:

<body ng-controller="MainCtrl">
  <div id="code">This is <b>some text</b> bla bla bla</div>
  <br />
  <input type="button" value="Mark!" ng-click="markText()" />
  <input type="button" value="Remove marks!" ng-click="removeMarks()" />
</body>

然后示例angularjs控制器MainCtrl可能如下所示:

app.controller('MainCtrl', function($scope) {

  var getSelectionPosition = function () { 
     var range = window.getSelection().getRangeAt(0);
     var preSelectionRange = range.cloneRange();
     preSelectionRange.selectNodeContents(document.getElementById("code"));
     preSelectionRange.setEnd(range.startContainer, range.startOffset);
     var start = preSelectionRange.toString().length;

     return {
        start: start,
        end: start + range.toString().length
     }
  }

  $scope.markText = function() {
    var currPosition = getSelectionPosition();
    var selection = window.getSelection().getRangeAt(0);
    var selectedText = selection.extractContents();
    var span = document.createElement("span");
    span.className = "Mark";
    span.setAttribute("PosStart", currPosition.start);
    span.setAttribute("PosEnd", currPosition.end);
    span.appendChild(selectedText);
    selection.insertNode(span);
  };

 $scope.removeMarks = function() {
    $(".Mark").each(function () {
        $(this).contents().unwrap();
    });
 };

});

请注意MainCtrl是body的angularjs控制器。按钮上的ng-click引用控制器范围中的markTextremoveMarks函数。函数中的逻辑与您在问题中引用的逻辑完全相同(和jsfiddle)。

除了移动控制器内部的功能外,您的JS代码都没有改变。再次,查看上面的plunker,看看实际的代码是否有效。