使用JS和VueJS将HTML内容减少到20个单词?

时间:2017-11-28 11:24:07

标签: javascript html vue.js vuejs2

我正在使用VueJS创建新闻源,我在渲染内容时遇到了一些问题。我遗憾地使用的API我现在无法正确改变以适应我的需要。 API为我提供了HTML标签中的所有内容,还可以包含图像和列表以及所有其他基础知识。我想要做的是创建一个"阅读更多"如果只是第一个" p"的文本,它将呈现前20个单词。标记并停在那里。

有没有人知道使用JS快速有效地做到这一点? 我当前的显示VueJS渲染如下:

<div v-for="news_item in news_items">
                        <div v-bind:class="{ 'col-md-4': display}">
                            <div class="card">
                                <div class="header">
                                    <h2>
                                        {{news_item.title}} <small>{{news_item.subtitle}}</small>
                                    </h2>
                                </div>
                                <div class="body" style="padding-top: 0">
                                    <div class="row" style="margin-right: -20px; margin-left: -20px;">
                                        <div class="col-md-12"
                                                style="padding-left: 0px; padding-right: 0px;">
                                            <img :src="news_item['thumbnail']"
                                                    class="img-responsive smaller-img" alt=""
                                                    style=" margin: 0 auto; max-height: 250px;">
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col-md-12">
                                            <div v-html="news_item.content"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

5 个答案:

答案 0 :(得分:1)

你似乎还没有尝试过任何东西,所以我会给你这些指示。如果您遇到特定问题,请再次询问。

  1. 制作component
  2. 组件应该接收html作为prop
  3. 组件应具有控制是否展开的数据项
  4. 该组件应具有computed,其中包含第一个段落标记的前20个单词。您可以使用textContent从HTML节点获取文本。
  5. 计算是最有可能构成挑战的部分。它看起来像这样

        blurb() {
          const div = document.createElement('div');
          div.innerHTML = this.content;  // this.content is the prop
          const firstP = div.querySelector('p');
          const text = firstP.textContent;
          const match = text.match(/(\S+\s*){0,20}/);
          return match[0];
        }
    

答案 1 :(得分:1)

这是使用指令的最佳时机:

https://vuejs.org/v2/guide/custom-directive.html

请参阅此处的codepen:https://codepen.io/huntleth/pen/GOXaLo

使用trim指令,您可以更改元素的内容。在上面的示例中,它将显示前5个单词后跟省略号。

如果您只是在纯粹的js解决方案之后,应该这样做:

    var resultString = str.split(' ').slice(0, 20).join(" ");

您可以使用trim指令并在el中搜索任何p标记,然后相应地更改其内容。

答案 2 :(得分:0)

粗略实施,Pure Js方法

&#13;
&#13;
document.getElementById("addContent").onclick = display;
document.getElementById("ellipsAnchor").onclick = hideEllipsis;

function display() {
  document.getElementById("instruction").classList+= " hide";
   let content = document.getElementById("inputbox").value;
   if(content.length > 30) {
     let sliced = content.slice(30);
     let unsliced = content.substring(0,29);
     let spantag = document.createElement("span");
     spantag.className = "toReplace hide"
     let text = document.createTextNode(sliced);
     spantag.appendChild(text);
     let spantag1 = document.createElement("span");
     let text1 = document.createTextNode(unsliced);
     spantag1.appendChild(text1);
     let contentTag =document.getElementById("content");
     contentTag.appendChild(spantag1)
     contentTag.appendChild(spantag)
     document.getElementById("ellipsis").classList -= "hide";
   }
}

function hideEllipsis(){
   document.getElementById("ellipsis").classList += " hide";   
   document.querySelectorAll("span.hide")[0].classList -= " hide"
}
&#13;
.hide {
  display : none;
}
&#13;
<textarea type="text" id="inputbox"></textarea>
<button id="addContent">
Show content
</button>
<div id="content">
</div>
<div class="hide" id="ellipsis">
<a href="#" id="ellipsAnchor">Read More..</a>
</div>

<div id="instruction">
Type more than 30 characters and click show content
</div>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您可以编写一个vue指令来解决此问题。

  1. 将max-height设置为div。
  2. 计算单词数,并在内容后附加“阅读更多..”链接。
  3. 将点击事件添加到“更多”中,以将DIV扩展到最大高度。

例如,请参见此Codepen

 let handler = ""

Vue.directive("viewmore", {
    inserted: function (el, binding){
      let maxlines = binding.value
      let lineheight = parseFloat(getComputedStyle(el).lineHeight)
      let paddingtop =  parseFloat(getComputedStyle(el).paddingTop) 
      let lines = (el.clientHeight) / lineheight ; 
      let maxheight = (lineheight * maxlines) + paddingtop + (lineheight/5)

      if(lines>maxlines){
          el.classList.add('vmore')
          el.style.maxHeight = maxheight + 'px'
          el.addEventListener('click', handler = ()=> {
          el.style.maxHeight = ""
          el.scrollIntoView({behavior: "smooth"})
          el.removeEventListener('click', handler)
          el.classList.remove('vmore')
        })
      }
    },
    unbind: function (el, binding) {
          el.removeEventListener('click', handler)
          handler = ""
    }
});

https://codepen.io/dagalti/pen/vPOZaB

它基于内容中的行。

代码:https://gist.github.com/dagalti/c8fc86cb791a51fe24e5dc647507c4a3

答案 4 :(得分:0)

在tom_h和Roy J的答案中进行扩展,这是我在vue应用程序中用来使省略号可点击的内容:

Vue.component("ellipsis", {
  template: "#ellipsis-template",
  props: ['content'],
  data: function() {
    return {
        wordLength: 3,  // default number of words to truncate
        showAll: false
    }
  }
});

<script type="text/x-template" id="ellipsis-template">
  <span v-if="content.split(' ').length>wordLength && showAll">{{content}}
    <a href="#" onclick="return false" @click="showAll=false"> (less)</a>
  </span>
  <span v-else-if="content.split(' ').length>wordLength && !showAll"> 
    {{content.split(" ").slice(0,wordLength).join(" ")}}
    <a href="#" onclick="return false" @click="showAll=true"> ...</a>
  </span>
  <span v-else>{{content}}</span>
</script>

要调用它:

<ellipsis :content="someData"></ellipsis>