代码之家  ›  专栏  ›  技术社区  ›  Varin

如何选择文本最后一行的第一个单词?(<h1>-<h6>,<p>元素)

  •  5
  • Varin  · 技术社区  · 9 年前

    我需要在我正在构建的站点上的每个h1-h6元素下添加一条小水平线。我目前正在添加after元素:

    h1, h2, h3, h4, h5, h6 {
      text-transform: uppercase;
      color: #000;
      margin-top: 0;
      margin-bottom: 2rem;
      font-weight: 800;
      color: #333;
      display: inline-block;
      position: relative;
      text-rendering: optimizeLegibility;
      font-family: $altfont;
      position: relative;
      &:after {
        content: '';
        position: absolute;
        bottom:0;
        left:0;
        width: 60px;
        height: 4px;
        background-color: $yellow;
      }
    }
    

    我还有一个小的jQuery函数来确保after元素总是比元素低20px:

    $(function () {
        $('h1, h2, h3, h4, h5, h6').each(function () {
    
                x = parseInt($(this).css('font-size'));
                $(this).css('line-height', (x + 20) + 'px');
    
        });
    });
    

    问题是,如果文本居中对齐或右对齐,after元素将显示在h1元素下,但不会显示在最后一行的第一个单词下。这是可以用JS/JQuery实现的吗?

    这是一张发生了什么的照片。在第二个示例中,我希望黄线显示在单词“Slice”下。

    enter image description here

    6 回复  |  直到 9 年前
        1
  •  1
  •   Louys Patrice Bessette    9 年前

    编辑


    需要4个循环才能实现你的要求。

    1. 添加 span 每一个字。
    2. 要查找 跨度
    3. 删除除最后一行之外的所有行上的跨距。

    CodePen

    (我留下了所有调试控制台日志) .

    $(function () {
      $('h1, h2, h3, h4, h5, h6').each(function () {
    
        x = parseInt($(this).css('font-size'));
        $(this).css('line-height', (x + 20) + 'px');
    
        findWord($(this));
    
      });
    
      function findWord(el){
    
        // Get the word array.
        var wordArr = el.html().split(" ");
    
        // Cycle words to add span on each words.
        for(i=0;i<wordArr.length;i++){
          console.log(wordArr[i]);
          wordArr[i] = "<span class='underliner'>"+wordArr[i]+"</span>";
        }
    
        // Update HTML.
        el.html(wordArr.join(" "));
    
        // Find the offset of the last line.
        var biggestOffset=0;
        el.find(".underliner").each(function(){
          console.log($(this).offset().top);
          if($(this).offset().top>biggestOffset){
            biggestOffset=$(this).offset().top;
          }
        });
    
        console.log("biggestOffset: "+biggestOffset);
    
        // Remove span on NOT the last line
        el.find(".underliner").each(function(){
          if($(this).offset().top<biggestOffset){
            $(this).replaceWith($(this).html());
          }
        });
    
        // On the last line, remove all spans except on the first word
        el.find(".underliner").not(":eq(0)").each(function(){
          $(this).replaceWith($(this).html());
        });
      }
    });
    h1, h2, h3, h4, h5, h6 {
      text-transform: uppercase;
      color: #000;
      margin-top: 0;
      margin-bottom: 2rem;
      font-weight: 800;
      /*color: #333;*/
      display: inline-block;
      position: relative;
      text-rendering: optimizeLegibility;
      font-family: $altfont;
      position: relative;
      
      text-align:center;  /* ADDED */
      
      /* REMOVED */
      /*&:after {
        content: '';
        position: absolute;
        bottom:0;
        left:0;
        width: 60px;
        height: 4px;
        background-color: &yellow;
      }*/
    }
    
    .underliner{
      text-decoration:underline;
      text-decoration-color: red
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <h1>This is a quite long H1 that will certainly wrap</h1>
    <h2>This is a quite long H2 that will certainly wrap</h2>
    <h3>This is a quite long H3 that will certainly wrap</h3>
    <h4>This is a quite long H4 that will certainly wrap</h4>
    <h5>This is a quite long H5 that will certainly wrap</h5>
    <h6>This is a quite long H6 that will certainly wrap</h6>




    第一个答案



    因为您已经使用了jQuery。。。

    $(this).append($("<div class='smallBar'>").css({"top":x+10})) 到脚本。。。
    并使用CSS定义 smallBar 就像你为 after 伪元素。

    CodePen

    $(function () {
      $('h1, h2, h3, h4, h5, h6').each(function () {
    
        x = parseInt($(this).css('font-size'));
        $(this).css('line-height', (x + 20) + 'px');
        $(this).append($("<div class='smallBar'>").css({"top":x+10}))
    
      });
    });
    h1, h2, h3, h4, h5, h6 {
      text-transform: uppercase;
      color: #000;
      margin-top: 0;
      margin-bottom: 2rem;
      font-weight: 800;
      /*color: #333;*/
      display: inline-block;
      position: relative;
      text-rendering: optimizeLegibility;
      font-family: $altfont;
      position: relative;
      /*&:after {
        content: '';
        position: absolute;
        bottom:0;
        left:0;
        width: 60px;
        height: 4px;
        background-color: &yellow;
      }*/
    }
    .smallBar{
      position: absolute;
        top:0;
        left:0;
        width: 60px;
        height: 4px;
        background-color: red;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h1>This is a quite long H1 that will certainly wrap</h1>
    <h2>This is a quite long H2 that will certainly wrap</h2>
    <h3>This is a quite long H3 that will certainly wrap</h3>
    <h4>This is a quite long H4 that will certainly wrap</h4>
    <h5>This is a quite long H5 that will certainly wrap</h5>
    <h6>This is a quite long H6 that will certainly wrap</h6>
        2
  •  1
  •   Vadim Ovchinnikov    9 年前

    我查找并突出显示最后一行第一个单词的算法:

    1. 遍历元素。
    2. innerText ).
    3. 从块中删除所有元素。
    4. 添加 span 带有文字和空白文本节点的 s到阵列)。
    5. 跨度 top 和最低 left 跨度

    highlightFirstWordOfLastLineForHeaders();
    
    /* apply highlighting on window resize */
    window.addEventListener("resize", highlightFirstWordOfLastLineForHeaders);
    
    /* Peforms highlightFirstWordOfLastLine call for every header element */
    function highlightFirstWordOfLastLineForHeaders() {
      var elements = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
    
      for (var i = 0; i < elements.length; i++) {
        highlightFirstWordOfLastLine(elements[i]);
      }
    }
    
    /* Peforms highlighting for single element */
    function highlightFirstWordOfLastLine(element) {
      var text = element.innerText.trim();
    
      /* get words list */
      var words = text.split(" ");
    
      /* removing all elements */
      while (element.firstChild) {
        element.removeChild(element.firstChild);
      }
    
      var spanArray = [];
    
      /* add spans with words and whitespaces */
      for (var i = 0; i < words.length; i++) {
        /* append span with word */
        var span = document.createElement("span");
        span.appendChild(document.createTextNode(words[i]));
        element.appendChild(span);
        /* append whitespace */
        element.appendChild(document.createTextNode(" "));
        /* save span element to array */
        spanArray.push(span);
      }
    
      /* sorting by highest top and lowest left */
      spanArray.sort(function(a, b) {
        var rectA = a.getBoundingClientRect();
        var rectB = b.getBoundingClientRect();
    
        var deltaTop = rectB.top - rectA.top;
    
        /* if differense is less then 1px */
        if (Math.abs(deltaTop) < 1) {
          return rectA.left - rectB.left;
        }
    
        return deltaTop;
      });
    
      /* appending highlighting to fist word of last line */
      spanArray[0].classList.add("selected");
    }
    .selected {
      border-bottom: 2px solid yellow;
    }
    <h1>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ultrices porta nibh, eu semper massa ullamcorper et.
    </h1>
    
    <h2>
      Curabitur in venenatis sapien. Nullam cursus ante ac enim dapibus, a egestas tellus mollis.
    </h2>
    
    <h3>
      Aenean tincidunt ligula et egestas suscipit. Proin euismod felis leo, egestas porta purus porta vitae. Morbi ut pulvinar quam, eu accumsan eros. Duis tristique pretium imperdiet. Integer nunc odio, consectetur vel leo vel, posuere venenatis nunc. Vestibulum sit amet arcu sit amet tortor faucibus maximus in id massa. Praesent vulputate, tellus nec aliquam tempor, ipsum erat tincidunt est, sit amet cursus turpis dui ac ipsum. Duis nec odio in felis aliquet sagittis sit amet in leo. Suspendisse potenti. Curabitur vitae sagittis diam. Duis id lectus cursus purus ultricies sollicitudin. Phasellus a ex sit amet eros lacinia fringilla sit amet sit amet sem. Proin luctus ornare risus at volutpat. Aliquam eleifend porttitor nulla. Sed facilisis mattis felis ut sodales.
    </h3>
    
    <h4>
      Quisque quis ultricies arcu. Aliquam feugiat non ipsum quis malesuada. Suspendisse ullamcorper, eros ut maximus hendrerit, sem velit lobortis turpis, non tristique justo magna eu nulla. Vestibulum maximus auctor ipsum sit amet finibus. Etiam commodo iaculis sem, vitae tincidunt libero. Phasellus lacus quam, semper ut pulvinar sed, accumsan a arcu. Suspendisse nulla velit, rhoncus id porttitor at, dictum ac ante. Sed eleifend vitae quam eget pretium.
    </h4>
    
    <h5>
      Duis semper rhoncus ultrices. Aliquam id elit nec quam fringilla gravida ac sed nisi. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lorem leo, rhoncus quis nulla eget, posuere pellentesque leo. Nam in nisi sit amet sem consequat sodales. Quisque leo urna, aliquet eu malesuada at, laoreet et lorem. Fusce est neque, fringilla id ex id, semper tincidunt mauris. Aliquam erat volutpat. Vestibulum sodales sodales tincidunt. Pellentesque elementum quis neque vel malesuada. Nulla non scelerisque enim, ut posuere tortor. Fusce vel neque tristique ipsum aliquet mattis at sed sapien.
    </h5>
    
    <h6>
      Praesent scelerisque magna libero, vitae commodo purus tincidunt in. Etiam placerat diam turpis, sit amet iaculis eros efficitur at. Sed porta, dui non condimentum vestibulum, libero enim cursus nibh, eu luctus ligula ante sed neque. Duis vestibulum lacus felis, at iaculis tellus malesuada at. Donec vehicula lacinia metus. Pellentesque non efficitur lectus. Etiam et consectetur massa. Proin et leo cursus, convallis diam sit amet, mattis arcu. Fusce posuere pharetra leo eget volutpat. Maecenas et posuere urna. Nullam a dolor eu ipsum placerat rhoncus. In cursus, mauris ut pulvinar pellentesque, diam orci facilisis ante, at sollicitudin libero turpis in libero. In maximus est eu nisl venenatis ultrices.
    </h6>

    jsFiddle .

        3
  •  0
  •   Lars Peterson    9 年前

    根据您编写代码的方式,这是不可能修复的。但是如果你愿意改变一些事情,我想我有一个解决方案。我的方法只有在你知道 font-size 正在寻址的元素的属性。

    更新的CSS

    h1 {
      font-size: 24px; /* ADDED */
      text-transform: uppercase;
      color: #000;
      margin-top: 0;
      margin-bottom: 2rem;
      font-weight: 800;
      color: #333;
      display: inline-block;
      position: relative;
      text-rendering: optimizeLegibility;
      font-family: $altfont;
      position: relative;
    
      &:after {
          content: '';
          position: absolute;
          top: 24px; /* FONT SIZE = DISTANCE */
          left:0;
          width: 60px;
          height: 4px;
          background-color: $yellow;
      }
    }
    

    这应该是可行的,但它未经测试。

    它通过了解

    编辑:我现在明白你想要完成什么了。

    媒体查询

    每次文本换行或最后一行的第一个单词移动时,都需要创建断点。

        4
  •  0
  •   Osama    9 年前
    var text = $(this:last).text().trim().split(" ");
    var last = text.pop();
    $( this:last).html(text.join(" ") + (text.length > 0 ? " <span class='lastWord'>" + last + "</span>" : last));
    };
    

     .lastWord{text-decoration:underline;}
    
        5
  •  0
  •   Daniel Vickers    9 年前

    写一些JS来查找h1的大小,如果h1的大小大于X,那么将是h1的大小,为了更好地测量,可能会在顶部添加一点。

    当h1换行到两行时,h1大小实际上加倍,这将导致if语句触发,并将样式添加到文本中。这是我必须为你完善的最接近的答案,如果你要求文本居中,我很抱歉。

    编辑:上述示例代码 .

    JS公司

    $(document).ready(function() {
    var h1Height = document.getElementsByTagName("h1").offsetHeight;
    
    function firstH1Wrap() {
        if (h1Height < /*line-height+5px*/){
            document.getElementsByTagName("h1").addClass('hide-line');
        } else {
            document.getElementsByTagName("h1").removeClass('hide-line');
        }
    }
    });
    
    $(window).resize(firstH1Wrap).trigger('resize')
    

    CSS

    h1, h2, h3, h4, h5, h6 {
        text-transform: uppercase;
        color: #000;
        margin-top: 0;
        margin-bottom: 2rem;
        font-weight: 800;
        color: #333;
        display: inline-block;
        position: relative;
        text-align: left;
        text-rendering: optimizeLegibility;
        font-family: $altfont;
        position: relative;
    }
    
    h1:after, h2:after, h3:after, h4:after, h5:after, h6:after {
        content: '';
        position: absolute;
        bottom:0;
        left:0;
        width: 60px;
        height: 4px;
        background-color: $yellow;
        display: block;
    }
    
    h1.hide-line:after, h2.hide-line:after, h3.hide-line:after, h4.hide-line:after, h5.hide-line:after, h6.hide-line:after {
        display: none;
    }
    

    如果要将所有标题的行高设置为1-6,则可以为所有标题运行相同的函数,因为它们具有相同的大小。如果不这样做,则需要为每个标题声明一个新变量,并将其构建到函数中或生成新的变量。

        6
  •  -3
  •   Lorenzo Catalano    9 年前

    top:'whatever is line-height + 20px'
    

    编辑:nm 我错过了“我希望黄线出现在单词“切片”下”部分