簡體   English   中英

如何選擇最后一行文字的第一個單詞? ( <h1> - <h6> , <p> 元素)

[英]How to select a first word of the last line of text? (<h1> - <h6>, <p> elements)

我需要在我正在構建的網站上的每個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');

    });
});

如果h1左側有文本對齊,則此方法有效 - 當文本換行為2行或更多行時,after元素將顯示在最后一行的第一個單詞下。

問題是,如果文本居中對齊或右對齊,則after元素將顯示在h1元素下,但不會顯示在最后一行的第一個單詞下。 這是可以用JS / JQuery完成的嗎?

這是一張發生了什么的照片。 在第二個例子中,我希望黃色線顯示在“Slice”一詞下面。

在此輸入圖像描述

編輯

這是一個很好的挑戰!
它需要4個循環來實現您的要求。

  1. 在每個單詞上添加span
  2. 要查找最后一行的span偏移量。
  3. 刪除除最后一行之外的所有行的跨度。
  4. 刪除除第一個以外的所有單詞的跨度。

CodePen

請參閱代碼中的注釋(我留下了所有調試console.logs)

 $(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以與after偽元素相同的方式定義smallBar

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> 

我找到並突出顯示最后一行第一個單詞的算法:

  1. 迭代元素。
  2. 獲取元素的文本( innerText )。
  3. 按空格(“”)符號拆分文本。
  4. 從塊中刪除所有元素。
  5. 添加span s的文字和空白文本節點(也保存這個span s到陣列)。
  6. 排序這個數組由span最高的top和最低leftspan的矩形。
  7. 將突出顯示類添加到此數組的頂部元素。

 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查看窗口大小調整的工作原理。

雖然未經測試,但這種邏輯很有意義

寫一些查看h1大小的JS,如果h1的大小大於X,那么h1的大小可能會稍微添加到頂部以獲得良好的度量。

然后使用和后面的偽類添加樣式到h1:0左邊:0。 但這意味着您的文本必須左對齊而不是中心。

當h1包裝到2行時,h1大小基本上加倍,然后將導致if語句觸發並將樣式添加到文本中。 這是我必須為你完美答案的最接近的答案。如果你要求文本為中心,我道歉。

編輯:上面的示例代碼

現在我不能說這會起作用,但這里有一些基於前面解釋過的方法的基本代碼。 我對javascript並不驚訝,所以你很可能需要繼續構建。 但至少這給了你一個起點我希望...

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的行高設置為相同,則可以為所有標題設置相同的函數,因為它們具有相同的大小,如果不這樣,則需要聲明一個新的變量每個標題並將其構建到函數中或創建新函數。

根據您編寫代碼的方式,無法修復此問題。 但是如果你願意改變一些事情,我想我有一個解決方案。 只有在知道要尋址的元素的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;
  }
}

這應該有效,但是未經測試。

它的工作原理是知道font-size ,然后使用該值作為上邊距。 因此,無論文本對齊方式如何變化,它都將始終位於同一位置。

編輯:我現在明白你想要完成什么。

這很難做到,因為這條線可能位於許多不同的位置。 我能想到的唯一解決方案是:

媒體查詢

您需要隨時和每次文本換行或最后一行的第一個單詞移動時創建斷點。

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));
};

並在CSS中添加此內容

 .lastWord{text-decoration:underline;}

剛放一個

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

到:after元素(並刪除底部)

編輯:nm我錯過了'我希望黃色線出現在“Slice”這個詞下面。 部分

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM