Vue-用span包裹文本选择并进行样式双向绑定?

时间:2018-10-18 15:29:05

标签: javascript vue.js vuejs2

我正在编写一个应用程序,允许用户在阅读时以不同的颜色突出显示文本。

我使用Selection API来实现此功能。但是,双向绑定存在问题。如果用户更改颜色,突出显示的文本将不会同时更新。

任何人都可以帮忙吗? http://jsfiddle.net/eywraw8t/424087/

为澄清我的问题,我想要的效果是,当用户更改颜色时,之前突出显示的所有文本也会更新。

复制:

  1. 默认颜色#ccc

  2. 突出显示一些文本(灰色)

  3. 选择另一种颜色,例如#ff0000(现在,如果您突出显示一些新文本,它将为红色,但是我希望之前突出显示的文本为红色,但是由于创建了跨度,它仍然是灰色的通过createElement,不绑定到vue的数据)

html:

<div id="app">
  <label v-for="color in colors">
    <input type="radio" v-model="currentColor" :value="color">
    {{color}}
  </label>
  <h4>Select Text To Highlight</h4>
  <p id="text" @mouseup="highlight">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatum ducimus veniam esse, nam rerum cumque repellat maiores! Explicabo laudantium, magni dignissimos impedit labore, dolores deserunt aspernatur eos quo, vero consequatur.
  </p>
</div>

js:

new Vue({
  el: "#app",
  data: {
    currentColor:'#ccc',
    colors: ["#ccc","#ff0000","#00ff00","#0000ff"],
    selectedRange: null
  },
  methods: {
     getSelectedText() {
      if (window.getSelection) {
        let sel = window.getSelection()
        if (sel.getRangeAt && sel.rangeCount) {
          this.selectedRange = sel.getRangeAt(0);
        }
        return window.getSelection().toString()
      } else if (document.selection) {
        this.selectedRange = document.selection.createRange()
        return document.selection.createRange().text
      }
      return ''
    },
    surroundSelection(color) {
      var span = document.createElement("span");
      span.className = 'highlight'
      span.style.fontWeight = "bold"
      span.style.color = color
      span.addEventListener("click", () => {
        console.log('click');
      });
      if (window.getSelection) {
        var sel = window.getSelection()
        if (sel.rangeCount) {
          var range = this.selectedRange.cloneRange()
          range.surroundContents(span)
          sel.removeAllRanges()
          sel.addRange(range)
        }
      }
    },
    highlight(){
        let text = this.getSelectedText();
      if (this.selectedRange && text) {
          this.surroundSelection(this.currentColor)
        }
    }
  }
})

1 个答案:

答案 0 :(得分:0)

为currentColor添加观察者可以解决此问题,因为仅当选择更改时,颜色才设置为span.style.color。

new Vue({
  el: "#app",
  data: {
    currentColor:'#ccc',
    currentSpan: null,
    colors: ["#ccc","#ff0000","#00ff00","#0000ff"],
    selectedRange: null
  },
  watch: {
    currentColor: function (newColor, oldColor) {
        if (!this.currentSpan) {
          return;
        }

        this.currentSpan.style.color = newColor;
    }
  },
  methods: {
    ...
    surrountSelection: function (color) {
      ...
      return span;
    },
    highlight: function () {
      if (this.selectedRange && text) {
        this.currentSpan = this.surroundText(this.currentColor);
      } else if (this.currentSpan) {
        this.currentSpan = null;
      }
    }
  }
}