在长文本

时间:2017-11-30 13:35:41

标签: javascript html node.js vue.js

我想点击一个文字,我的意思是它的每一个字。 现在我知道你可以用<span>标签包装每个Word。这很适合 句子和段落,但我希望能够使用长文本(文章到书籍),我想这个机制不适用于此。

所以在某种程度上我想添加特定的eventlistener,当我点击它而不是事先,因为用<span>将整个书中的每个单词包装起来只会导致很多开销。

所以我想知道是否有类似于包装的东西能为我做到这一点?

我能想到的另一种方法是将文本和事件监听器放入这样的对象中:

[{"word: 'Hello'", event:EventListenerFunction},{"word":'World!', event: EventListerenerFunction},...]

通过这种方式,我可以在服务器上而不是在客户端上计算整个事物,并且可以创建所需的更多信息。它也有其他我想用文本做的东西的优点。

现在这种方法的问题在于显示。很容易在vue.js中显示文本,如:{{ textObject.text }}(如果对象的结构当然是正确的。否则你需要事先过滤这些单词)。但是如何在不丢失Object中的信息的情况下显示单词并使事件监听器工作?

我的第三个理论思想是给父html-tag一个eventlistener,它以某种方式将被点击的单词作为参数。这将适用于围绕单词方法的包装span。但没有它?

你还有其他想法吗?

2 个答案:

答案 0 :(得分:2)

有跨度:

&#13;
&#13;
var page = 'Lorem ipsum dolor sit amet, cu eum eros vitae persequeris, laudem possit nam ex. Labore eloquentiam per an. Sit ex omnesque interpretaris, habeo tantas eos ad, ea eos ludus inciderint. Facete tritani pro ei, vim evertitur liberavisse ex. Ridens indoctum duo cu, est utamur aliquando expetendis ne. Cum nusquam definiebas ex, id esse neglegentur cum, eu libris bonorum volumus vis. Ius et quis omnis graeco, no his nullam perpetua dissentiet. No vix possim scripserit consequuntur, te mnesarchum philosophia sed. Ne mea putent iudicabit, in eam ipsum viris dicunt. Eum amet accommodare ex, sint malis adversarium at qui.'

new Vue({
  el: '#app',
  data: {
    page: ''
  },
  computed: {
    pageContent () {
      return this.page.replace(/\b(\w+?)\b/g, '<span>$1</span>')
    }
  },
  methods: {
    doSomething (e) {
      if (e.target.nodeName === 'SPAN')
        console.log(e.target.textContent)
    }
  },
  created () {
    // load external data
    this.page = page
  }
})
&#13;
<div id="app">
  <p @click="doSomething" v-html="pageContent"></p>
</div>

<script src="https://unpkg.com/vue@2.5.9/dist/vue.min.js"></script>
&#13;
&#13;
&#13;

没有跨度:

&#13;
&#13;
var book = 'Lorem ipsum dolor sit amet, cu eum eros vitae persequeris, laudem possit nam ex. Labore eloquentiam per an. Sit ex omnesque interpretaris, habeo tantas eos ad, ea eos ludus inciderint. Facete tritani pro ei, vim evertitur liberavisse ex. Ridens indoctum duo cu, est utamur aliquando expetendis ne. Cum nusquam definiebas ex, id esse neglegentur cum, eu libris bonorum volumus vis. Ius et quis omnis graeco, no his nullam perpetua dissentiet. No vix possim scripserit consequuntur, te mnesarchum philosophia sed. Ne mea putent iudicabit, in eam ipsum viris dicunt. Eum amet accommodare ex, sint malis adversarium at qui.'

new Vue({
  el: '#app',
  data: {
    book: ''
  },
  methods: {
    doSomething (e) {
      var content = e.target.textContent
      var pos = window.getSelection().anchorOffset
      content = content
        .substring(0, content.indexOf(' ', pos))
        .trim()
      content = content
        .substr(content.lastIndexOf(' ') + 1)
        .replace(/[.,:;!?()+-]/g, '')
        
      console.log(content)
    }
  },
  created () {
    // load external data
    this.book = book
  }
})
&#13;
<div id="app">
  <p @click="doSomething" v-html="book"></p>
</div>

<script src="https://unpkg.com/vue@2.5.9/dist/vue.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以使用window.getSelection()获取文字中的位置,然后找到其周围的字符。

一个角落的情况:如果你有一个格式标签(比如我的例子中的粗体)会破坏一个单词,你将得到你单击的单词的一部分,而不是整个单词。

var page = `Lorem ipsum dolor sit amet, cu eum eros vitae persequeris, laudem possit nam ex.
Labore eloquentiam per an.
Sit ex omnesque interpretaris, habeo tantas eos ad, ea eos ludus inciderint.
<i>Facete tritani pro ei</i>, vim evertitur liberavisse ex.
Ridens indoctum duo cu, est utamur aliquando expetendis ne. <b>Cum nusquam defin</b>iebas ex, id esse neglegentur cum, eu libris bonorum volumus vis. Ius et quis omnis graeco, no his nullam perpetua dissentiet. No vix possim scripserit consequuntur, te mnesarchum philosophia sed. Ne mea putent iudicabit, in eam ipsum viris dicunt. Eum amet accommodare ex, sint malis adversarium at qui.`

new Vue({
  el: '#app',
  data: {
    page
  },
  methods: {
    doSomething (e) {
      const sel = window.getSelection();
      const text = sel.anchorNode.textContent;
      const lmatch = text.substr(0, sel.anchorOffset).match(/[\s\S]*\s/);
      const offset = lmatch ? lmatch[0].length : 0;
      const match = text.substr(offset).match(/\w+/);
      
      console.log(match && match[0]);
    }
  }
})
<div id="app">
  <p @click="doSomething" v-html="page"></p>
</div>

<script src="https://unpkg.com/vue@2.5.9/dist/vue.min.js"></script>