ฉันจะนับบรรทัดข้อความภายในองค์ประกอบ DOM ได้อย่างไร ให้ฉัน?


127

ฉันสงสัยว่ามีวิธีนับเส้นใน div หรือไม่ สมมติว่าเรามี div ดังนี้:

<div id="content">hello how are you?</div>

Div อาจมีหนึ่งหรือสองบรรทัดหรือสี่บรรทัดก็ได้ทั้งนี้ขึ้นอยู่กับหลายปัจจัย มีวิธีใดสำหรับบทที่จะรู้?

กล่าวอีกนัยหนึ่งการหยุดพักอัตโนมัติแสดงใน DOM หรือไม่

คำตอบ:


89

หากขนาดของ div ขึ้นอยู่กับเนื้อหา (ซึ่งฉันถือว่าเป็นกรณีจากคำอธิบายของคุณ) คุณสามารถดึงความสูงของ div โดยใช้:

var divHeight = document.getElementById('content').offsetHeight;

และหารด้วยความสูงของบรรทัดแบบอักษร:

document.getElementById('content').style.lineHeight;

หรือหากต้องการรับความสูงของเส้นหากยังไม่ได้กำหนดไว้อย่างชัดเจน:

var element = document.getElementById('content');
document.defaultView.getComputedStyle(element, null).getPropertyValue("lineHeight");

คุณจะต้องคำนึงถึงช่องว่างภายในและระยะห่างระหว่างบรรทัดด้วย

แก้ไข

การทดสอบที่มีอยู่ในตัวโดยสมบูรณ์การตั้งค่าความสูงของเส้นอย่างชัดเจน:

function countLines() {
   var el = document.getElementById('content');
   var divHeight = el.offsetHeight
   var lineHeight = parseInt(el.style.lineHeight);
   var lines = divHeight / lineHeight;
   alert("Lines: " + lines);
}
<body onload="countLines();">
  <div id="content" style="width: 80px; line-height: 20px">
    hello how are you? hello how are you? hello how are you? hello how are you?
  </div>
</body>


7
เป็นการเริ่มต้นที่ดียกเว้นว่าความสูงของเส้นอาจไม่ได้ถูกกำหนดไว้เสมอไป คุณควรได้รับสิ่งนั้นจากรูปแบบที่คำนวณขององค์ประกอบ
Chetan S

ในความคิดที่สองความสูงของเส้นไม่จำเป็นต้องเป็นตัวเลขเสมอไป (หรือเป็นพิกเซล) ดังนั้นหากโค้ดของคุณต้องใช้และรูปแบบ CSS ของคุณอนุญาตคุณควรกำหนดความสูงของเส้นเป็นพิกเซล
Chetan S

6
@Chetan - โดยทั่วไปการตั้งค่าขนาดข้อความเป็นพิกเซลถือเป็นสิ่งที่ไม่ดี astahost.com/Sizes-Webdesign-Em-Vs-Px-t8926.html
annakata

6
สิ่งนี้อาจใช้ได้เฉพาะในกรณีที่ง่ายที่สุดเท่านั้น (เช่นตัวอย่างของฉัน) หากมีช่วงภายในองค์ประกอบอินไลน์บล็อกและอื่น ๆ การแบ่งตามขนาดตัวอักษร (หลัก) อย่างตรงไปตรงมาจะไร้ค่า ยังดีกว่าไม่มีอะไรขอบคุณ
buti-oxa

2
ฉันคิดว่าวิธีที่ดีกว่าในการคำนวณline-height(ที่ไม่ได้ตั้งค่าไว้อย่างชัดเจน) น่าจะใช้window.getComputedStyle(element, null).getPropertyValue('line-height')
rnevius

20

วิธีแก้ไขอย่างหนึ่งคือการใส่ทุกคำในแท็กสแปนโดยใช้สคริปต์ จากนั้นหากมิติ Y ของแท็กช่วงที่กำหนดมีค่าน้อยกว่าของแท็กรุ่นก่อนหน้าจะเกิดการแตกบรรทัด


ฉลาด! คุณจะทำอย่างไร? ฉันเดาว่าคุณถือว่าเป็นข้อความเพียงย่อหน้าเท่านั้น (ดังที่ฉันมีในตัวอย่าง) ฉันไม่ได้คำนึงถึงข้อ จำกัด นี้ แต่มันอาจจะโอเคหากสคริปต์ไม่ผิดพลาดเมื่อมีสิ่งอื่นอยู่ในย่อหน้า
buti-oxa

1
ในความคิดที่สองวิธีนี้จะล้มเหลวหากมีระยะห่างในแนวตั้งในแนวตั้ง ดังนั้นแม้แต่ข้อความเฉพาะย่อหน้าก็อาจนับผิดได้
buti-oxa

div ของฉันมีข้อความและรูปภาพ ... โชคดีที่รูปภาพอยู่ในตำแหน่งที่แน่นอนดังนั้นฉันคิดว่าพวกเขาจะถูกยกเว้น : D อย่างไรก็ตามฉันใช้รหัสเดียวกับที่คุณแนะนำ แต่ด้วย div ไม่ใช่สแปนขอขอบคุณที่ +1!
Albert Renshaw

20

ตรวจสอบฟังก์ชันgetClientRects ()ซึ่งสามารถใช้เพื่อนับจำนวนบรรทัดในองค์ประกอบ นี่คือตัวอย่างวิธีการใช้งาน

var message_lines = $("#message_container")[0].getClientRects();

ส่งคืนวัตถุ javascript DOM สามารถทราบจำนวนเส้นได้โดยทำสิ่งนี้:

var amount_of_lines = message_lines.length;

สามารถคืนค่าความสูงของแต่ละบรรทัดและอื่น ๆ ดูสิ่งต่างๆทั้งหมดที่ทำได้โดยเพิ่มสิ่งนี้ลงในสคริปต์ของคุณจากนั้นดูในบันทึกคอนโซลของคุณ

console.log("");
console.log("message_lines");
console.log(".............................................");
console.dir(message_lines);
console.log("");

แม้ว่าสิ่งที่ควรทราบจะใช้ได้ก็ต่อเมื่อองค์ประกอบที่มีอยู่ในบรรทัดอย่างไรก็ตามคุณสามารถล้อมรอบองค์ประกอบแบบอินไลน์ที่มีองค์ประกอบบล็อกเพื่อควบคุมความกว้างดังนี้:

<div style="width:300px;" id="block_message_container">
<div style="display:inline;" id="message_container">
..Text of the post..
</div>
</div>

แม้ว่าฉันจะไม่แนะนำให้เขียนโค้ดแบบยาก ๆ ในสไตล์นั้น เป็นเพียงตัวอย่างสำหรับวัตถุประสงค์


3
คำตอบนี้และคำตอบอื่น ๆ จาก getClientRects นั้นดีกว่าคำตอบที่ยอมรับมาก
matteo

2
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ ขอบคุณ @ Digital-Christie
Antuan

12

ฉันไม่พอใจกับคำตอบที่นี่และคำถามอื่น ๆ คำตอบที่ได้รับคะแนนสูงสุดไม่ได้คำนึงถึงpaddingหรือborderคำนึงถึงดังนั้นจึงเห็นได้ชัดว่าไม่สนใจbox-sizingเช่นกัน คำตอบของฉันรวมเทคนิคบางอย่างไว้ที่นี่และในหัวข้ออื่น ๆ เพื่อให้ได้โซลูชันที่ตรงกับความพึงพอใจของฉัน

มันไม่ได้สมบูรณ์แบบ: เมื่อไม่มีค่าตัวเลขก็สามารถที่จะดึงสำหรับline-height(เช่นnormalหรือinherit) ก็แค่ใช้คูณด้วยfont-size 1.2บางทีอาจมีคนอื่นแนะนำวิธีที่เชื่อถือได้ในการตรวจจับค่าพิกเซลในกรณีเหล่านั้น

นอกเหนือจากนั้นมันยังสามารถจัดการกับสไตล์และเคสส่วนใหญ่ที่ฉันโยนทิ้งไปได้อย่างถูกต้อง

jsFiddleสำหรับเล่นและทดสอบ อินไลน์ด้านล่างด้วย

function countLines(target) {
  var style = window.getComputedStyle(target, null);
  var height = parseInt(style.getPropertyValue("height"));
  var font_size = parseInt(style.getPropertyValue("font-size"));
  var line_height = parseInt(style.getPropertyValue("line-height"));
  var box_sizing = style.getPropertyValue("box-sizing");
  
  if(isNaN(line_height)) line_height = font_size * 1.2;
 
  if(box_sizing=='border-box')
  {
    var padding_top = parseInt(style.getPropertyValue("padding-top"));
    var padding_bottom = parseInt(style.getPropertyValue("padding-bottom"));
    var border_top = parseInt(style.getPropertyValue("border-top-width"));
    var border_bottom = parseInt(style.getPropertyValue("border-bottom-width"));
    height = height - padding_top - padding_bottom - border_top - border_bottom
  }
  var lines = Math.ceil(height / line_height);
  alert("Lines: " + lines);
  return lines;
}
countLines(document.getElementById("foo"));
div
{
  padding:100px 0 10% 0;
  background: pink;
  box-sizing: border-box;
  border:30px solid red;
}
<div id="foo">
x<br>
x<br>
x<br>
x<br>
</div>


helpfull post ... ขอบคุณ
Sinto

การพิจารณาที่ดี แต่ในกรณีของฉันความสูงของ div บรรทัดหนึ่งมากกว่าความสูงของบรรทัด 1px โดยไม่มีช่องว่างภายในและเส้นขอบ ดังนั้นการกำหนดความสูงของเส้นโดยการรวมคำตอบและคำตอบของ @ e-info128 (วิธีการ cloneNode) อาจเป็นทางเลือกที่ดีกว่า
Eric

8

โคลนวัตถุคอนเทนเนอร์และเขียน 2 ตัวอักษรและคำนวณความสูง สิ่งนี้จะคืนค่าความสูงจริงโดยใช้สไตล์ทั้งหมดความสูงของเส้น ฯลฯ ตอนนี้ให้คำนวณวัตถุความสูง / ขนาดของตัวอักษร ใน Jquery ความสูงจะช่วยเพิ่มช่องว่างระยะขอบและเส้นขอบได้ดีมากการคำนวณความสูงจริงของแต่ละบรรทัด:

other = obj.clone();
other.html('a<br>b').hide().appendTo('body');
size = other.height() / 2;
other.remove();
lines = obj.height() /  size;

หากคุณใช้แบบอักษรที่หายากซึ่งมีความสูงของแต่ละตัวอักษรต่างกันจะไม่ได้ผล แต่ใช้งานได้กับฟอนต์ปกติทั้งหมดเช่น Arial, mono, comics, Verdana เป็นต้นทดสอบด้วยฟอนต์ของคุณ

ตัวอย่าง:

<div id="content" style="width: 100px">hello how are you? hello how are you? hello how are you?</div>
<script type="text/javascript">
$(document).ready(function(){

  calculate = function(obj){
    other = obj.clone();
    other.html('a<br>b').hide().appendTo('body');
    size = other.height() / 2;
    other.remove();
    return obj.height() /  size;
  }

  n = calculate($('#content'));
  alert(n + ' lines');
});
</script>

ผลลัพธ์: 6 Lines

ใช้งานได้กับเบราว์เซอร์ทั้งหมดโดยไม่มีฟังก์ชันที่หายากไม่ได้มาตรฐาน

ตรวจสอบ: https://jsfiddle.net/gzceamtr/


ก่อนอื่นฉันอยากจะบอกว่าขอบคุณมากแค่สิ่งที่ฉันกำลังมองหา คุณช่วยอธิบายแต่ละบรรทัดของฟังก์ชันการคำนวณได้ไหม ขอบคุณมากในล่วงหน้า. SYA :)
LebCit

1
สำหรับผู้ที่ต้องการคำตอบที่ไม่ใช่ jQuery: clonecloneNode, hidestyle.visibility = "hidden", html('a<br>b')textContent='a\r\nb', appendTo('body')document.documentElement.appendChild, height()getBoundingClientRect().height
Eric

เนื่องจากฉันได้รับข้อผิดพลาด 1px ระหว่างความสูงของบรรทัดและความสูงของ div ฉันจึงแนะนำคำตอบนี้ การรวมสิ่งนี้และคำตอบของ @ Jeff จะดียิ่งขึ้น
Eric

6

สำหรับผู้ที่ใช้ jQuery http://jsfiddle.net/EppA2/3/

function getRows(selector) {
    var height = $(selector).height();
    var line_height = $(selector).css('line-height');
    line_height = parseFloat(line_height)
    var rows = height / line_height;
    return Math.round(rows);
}

jsfiddle.net/EppA2/9มีความแม่นยำน้อยกว่า แต่ตามนี้เบราว์เซอร์ต่างๆอาจรองรับได้ดีกว่า
penkovsky

8
เมื่อ jQuery ส่งคืนค่า "ปกติ" $(selector).css('line-height');คุณจะไม่ได้รับตัวเลขจากฟังก์ชันนั้น
bafromca

5

ฉันเชื่อว่ามันเป็นไปไม่ได้ในตอนนี้ มันเป็นแม้ว่า

การใช้งาน getClientRects ของ IE7 ทำในสิ่งที่ฉันต้องการ เปิดหน้านี้ใน IE8 ลองรีเฟรชโดยปรับความกว้างของหน้าต่างและดูว่าจำนวนบรรทัดในองค์ประกอบแรกเปลี่ยนไปอย่างไร นี่คือบรรทัดสำคัญของจาวาสคริปต์จากหน้านั้น:

var rects = elementList[i].getClientRects();
var p = document.createElement('p');
p.appendChild(document.createTextNode('\'' + elementList[i].tagName + '\' element has ' + rects.length + ' line(s).'));

น่าเสียดายสำหรับฉัน Firefox จะส่งคืนสี่เหลี่ยมไคลเอ็นต์หนึ่งรายการต่อองค์ประกอบเสมอและ IE8 ก็ทำเช่นเดียวกันในตอนนี้ (หน้าของ Martin Honnen ทำงานได้ในวันนี้เนื่องจาก IE แสดงผลในมุมมองที่เข้ากันได้กับ IE กด F12 ใน IE8 เพื่อเล่นกับโหมดต่างๆ)

นี่เป็นเรื่องน่าเศร้า ดูเหมือนอีกครั้งการใช้งานข้อกำหนดที่แท้จริงของ Firefox แต่ไร้ค่าจะได้รับประโยชน์จาก Microsoft หรือฉันพลาดสถานการณ์ที่ getClientRects ใหม่อาจช่วยนักพัฒนาได้?


2
ตามที่ระบุไว้ในเอกสารelement.getClientRectsของ Mozilla อย่างน้อยสำหรับองค์ประกอบแบบอินไลน์ข้อมูลจำเพาะ W3C จะส่งผลให้เป็น rect สำหรับแต่ละบรรทัดของข้อความ - ไม่เหมาะ แต่อย่างน้อยก็มีบางอย่าง
natevw

getClientRects (). length เป็นวิธีที่ถูกต้อง getComputedStyle () อาจส่งคืนค่าเช่น "inherit", "normal" และ "auto"
Binyamin

4

จากคำตอบของ GuyPaddock จากด้านบนสิ่งนี้ดูเหมือนจะใช้ได้กับฉัน

function getLinesCount(element) {
  var prevLH = element.style.lineHeight;
  var factor = 1000;
  element.style.lineHeight = factor + 'px';

  var height = element.getBoundingClientRect().height;
  element.style.lineHeight = prevLH;

  return Math.floor(height / factor);
}

เคล็ดลับในที่นี้คือการเพิ่มความสูงของเส้นให้มากจน "กลืน" ความแตกต่างของเบราว์เซอร์ / ระบบปฏิบัติการใด ๆ ในการแสดงผลแบบอักษร

ตรวจสอบด้วยสไตล์ที่หลากหลายและขนาดตัวอักษร / ตระกูลที่แตกต่างกันสิ่งเดียวที่ไม่ได้คำนึงถึง (เนื่องจากในกรณีของฉันมันไม่สำคัญ) คือช่องว่างภายในซึ่งสามารถเพิ่มลงในโซลูชันได้อย่างง่ายดาย


2

ไม่ไม่น่าเชื่อถือ มีตัวแปรที่ไม่รู้จักมากเกินไป

  1. ระบบปฏิบัติการใด (DPI ที่แตกต่างกันรูปแบบแบบอักษร ฯลฯ ... )
  2. พวกเขาปรับขนาดแบบอักษรเพราะตาบอดจริงหรือไม่?
  3. Heck ในเบราว์เซอร์ webkit คุณสามารถปรับขนาดกล่องข้อความได้ตามที่ใจต้องการ

รายการต่อไป สักวันฉันหวังว่าจะมีวิธีการเช่นนี้ในการทำให้สำเร็จด้วย JavaScript ได้อย่างน่าเชื่อถือ แต่จนกว่าจะถึงวันนั้นคุณก็โชคไม่ดี

ฉันเกลียดคำตอบแบบนี้และหวังว่าจะมีคนพิสูจน์ว่าฉันผิด


3
หากคุณนับเส้นหลังจากการแสดงผลสิ่งที่ไม่รู้จักทั้งหมดนั้นไม่เกี่ยวข้อง แน่นอนว่าประเด็นของคุณมีผลหากคุณพยายาม "คาดเดา" จำนวนบรรทัดที่เบราว์เซอร์ใช้ในการแสดงผลข้อความ
simon

ฉันคิดว่าตัวแปรของผู้ใช้ที่ซูมเข้าและ / หรือเปลี่ยนขนาดตัวอักษรสามารถละเว้นได้ ฉันไม่เคยเห็นไซต์ที่มีการออกแบบที่ปรับให้เหมาะสมเพื่อรองรับการปรับขนาดหน้าต่าง (หลังจากโหลดหน้า) หรือเปลี่ยนขนาดตัวอักษรเบราว์เซอร์อย่างชาญฉลาดดังนั้นฉันไม่คิดว่าสิ่งเหล่านี้เป็นปัจจัยสำคัญในคำถามเฉพาะนี้ อย่างไรก็ตามฉันยอมรับว่าไม่มีวิธีแก้ปัญหาที่เชื่อถือได้มีเพียง "guesstimations" ที่อิงตามพิกเซลตามที่คนอื่น ๆ ระบุ
Kalko

2

คุณควรจะสามารถแบ่ง ('\ n'). length และได้รับการแบ่งบรรทัด

อัปเดต: ใช้งานได้กับ FF / Chrome แต่ไม่ใช่ IE

<html>
<head>
<script src="jquery-1.3.2.min.js"></script>
<script>
    $(document).ready(function() {
        var arr = $("div").text().split('\n');
        for (var i = 0; i < arr.length; i++)
            $("div").after(i + '=' + arr[i] + '<br/>');
    });
</script>
</head>
<body>
<div>One
Two
Three</div>
</body>
</html>

1
ลองใช้และแจ้งให้เราทราบว่าจะไปอย่างไร ฉันตายจริงจังไม่ได้ประชดประชัน คุณสามารถใช้รหัสนี้ในคอนโซลของ FireBug ในหน้านี้ var the_text = $ ('. welovestackoverflow p'). text (); var numlines = the_text.split ("\ n"). length; การแจ้งเตือน (numlines);
KyleFarris

3
ขอบคุณสำหรับ Surprize นี้ฉันไม่รู้ว่ามันเป็นไปได้ แต่นี่ไม่ใช่สิ่งที่ฉันต้องการ ดูเหมือนว่า Jquery จะนับตัวแบ่งบรรทัดยากในแหล่งที่มาและฉันสนใจการแบ่งบรรทัดอัตโนมัติในผลลัพธ์ ในกรณีของ div "One Two Three" ผลลัพธ์ควรเป็น 1 เนื่องจากเบราว์เซอร์ใส่ข้อความทั้งหมดไว้ในบรรทัดเดียว
buti-oxa

แล้วฉันก็เข้าใจคำถามของคุณผิด คุณต้องการหาความสูงบรรทัดที่คำนวณแล้ว
Chad Grant

1

getClientRectsส่งคืนไคลเอ็นต์ rects เช่นนี้และหากคุณต้องการรับบรรทัดให้ใช้ฟังก์ชัน follow เช่นนี้

function getRowRects(element) {
    var rects = [],
        clientRects = element.getClientRects(),
        len = clientRects.length,
        clientRect, top, rectsLen, rect, i;

    for(i=0; i<len; i++) {
        has = false;
        rectsLen = rects.length;
        clientRect = clientRects[i];
        top = clientRect.top;
        while(rectsLen--) {
            rect = rects[rectsLen];
            if (rect.top == top) {
                has = true;
                break;
            }
        }
        if(has) {
            rect.right = rect.right > clientRect.right ? rect.right : clientRect.right;
            rect.width = rect.right - rect.left;
        }
        else {
            rects.push({
                top: clientRect.top,
                right: clientRect.right,
                bottom: clientRect.bottom,
                left: clientRect.left,
                width: clientRect.width,
                height: clientRect.height
            });
        }
    }
    return rects;
}

1

ฉันพบวิธีคำนวณเลขบรรทัดเมื่อฉันพัฒนาตัวแก้ไข html วิธีการหลักคือ:

  1. ใน IE คุณสามารถเรียก getBoundingClientRects ได้โดยจะส่งกลับแต่ละบรรทัดเป็นสี่เหลี่ยมผืนผ้า

  2. ใน webkit หรือเอ็นจิ้น html มาตรฐานใหม่จะส่งกลับแต่ละองค์ประกอบหรือสี่เหลี่ยมไคลเอนต์ของโหนดในกรณีนี้คุณสามารถเปรียบเทียบสี่เหลี่ยมแต่ละอันได้ฉันหมายความว่าแต่ละรูปสี่เหลี่ยมจะต้องมีขนาดใหญ่ที่สุดดังนั้นคุณสามารถเพิกเฉยต่อรูปสี่เหลี่ยมเหล่านั้นที่ความสูงเล็กกว่า (ถ้า มีด้านบนของสี่เหลี่ยมผืนผ้าเล็กกว่าและด้านล่างใหญ่กว่าเงื่อนไขเป็นจริง)

มาดูผลการทดสอบกัน:

ใส่คำอธิบายภาพที่นี่

สี่เหลี่ยมผืนผ้าสีเขียวคือสี่เหลี่ยมผืนผ้าที่ใหญ่ที่สุดในแต่ละแถว

สี่เหลี่ยมผืนผ้าสีแดงคือขอบเขตการเลือก

สี่เหลี่ยมผืนผ้าสีน้ำเงินเป็นขอบเขตตั้งแต่เริ่มต้นจนถึงการเลือกหลังจากขยายเราเห็นว่าอาจมีขนาดใหญ่กว่าสี่เหลี่ยมผืนผ้าสีแดงดังนั้นเราต้องตรวจสอบด้านล่างของสี่เหลี่ยมผืนผ้าแต่ละอันเพื่อ จำกัด ว่าจะต้องมีขนาดเล็กกว่าด้านล่างของสี่เหลี่ยมผืนผ้าสีแดง

        var lineCount = "?";
        var rects;
        if (window.getSelection) {
            //Get all client rectangles from body start to selection, count those rectangles that has the max bottom and min top
            var bounding = {};
            var range = window.getSelection().getRangeAt(0);//As this is the demo code, I dont check the range count
            bounding = range.getBoundingClientRect();//!!!GET BOUNDING BEFORE SET START!!!

            //Get bounding and fix it , when the cursor is in the last character of lineCount, it may expand to the next lineCount.
            var boundingTop = bounding.top;
            var boundingBottom = bounding.bottom;
            var node = range.startContainer;
            if (node.nodeType !== 1) {
                node = node.parentNode;
            }
            var style = window.getComputedStyle(node);
            var lineHeight = parseInt(style.lineHeight);
            if (!isNaN(lineHeight)) {
                boundingBottom = boundingTop + lineHeight;
            }
            else {
                var fontSize = parseInt(style.fontSize);
                if (!isNaN(fontSize)) {
                    boundingBottom = boundingTop + fontSize;
                }
            }
            range = range.cloneRange();

            //Now we have enougn datas to compare

            range.setStart(body, 0);
            rects = range.getClientRects();
            lineCount = 0;
            var flags = {};//Mark a flags to avoid of check some repeat lines again
            for (var i = 0; i < rects.length; i++) {
                var rect = rects[i];
                if (rect.width === 0 && rect.height === 0) {//Ignore zero rectangles
                    continue;
                }
                if (rect.bottom > boundingBottom) {//Check if current rectangle out of the real bounding of selection
                    break;
                }
                var top = rect.top;
                var bottom = rect.bottom;
                if (flags[top]) {
                    continue;
                }
                flags[top] = 1;

                //Check if there is no rectangle contains this rectangle in vertical direction.
                var succ = true;
                for (var j = 0; j < rects.length; j++) {
                    var rect2 = rects[j];
                    if (j !== i && rect2.top < top && rect2.bottom > bottom) {
                        succ = false;
                        break;
                    }
                }
                //If succ, add lineCount 1
                if (succ) {
                    lineCount++;
                }
            }
        }
        else if (editor.document.selection) {//IN IE8 getClientRects returns each single lineCount as a rectangle
            var range = body.createTextRange();
            range.setEndPoint("EndToEnd", range);
            rects = range.getClientRects();
            lineCount = rects.length;
        }
        //Now we get lineCount here

1

ลองใช้วิธีนี้:

function calculateLineCount(element) {
  var lineHeightBefore = element.css("line-height"),
      boxSizing        = element.css("box-sizing"),
      height,
      lineCount;

  // Force the line height to a known value
  element.css("line-height", "1px");

  // Take a snapshot of the height
  height = parseFloat(element.css("height"));

  // Reset the line height
  element.css("line-height", lineHeightBefore);

  if (boxSizing == "border-box") {
    // With "border-box", padding cuts into the content, so we have to subtract
    // it out
    var paddingTop    = parseFloat(element.css("padding-top")),
        paddingBottom = parseFloat(element.css("padding-bottom"));

    height -= (paddingTop + paddingBottom);
  }

  // The height is the line count
  lineCount = height;

  return lineCount;
}

คุณสามารถดูการทำงานได้ที่นี่: https://jsfiddle.net/u0r6avnt/

ลองปรับขนาดแผงในหน้า (เพื่อทำให้ด้านขวาของหน้ากว้างขึ้นหรือสั้นลง) แล้วเรียกใช้อีกครั้งเพื่อดูว่าสามารถบอกจำนวนบรรทัดได้อย่างน่าเชื่อถือ

ปัญหานี้ยากกว่าที่คิด แต่ปัญหาส่วนใหญ่มาจากสองแหล่ง:

  1. การแสดงข้อความอยู่ในระดับต่ำเกินไปในเบราว์เซอร์ที่จะสอบถามโดยตรงจาก JavaScript แม้แต่ตัวเลือกหลอก CSS :: บรรทัดแรกก็ไม่ได้ทำงานเหมือนกับตัวเลือกอื่น ๆ (คุณไม่สามารถเปลี่ยนกลับได้เช่นใช้สไตล์กับทั้งหมดยกเว้นบรรทัดแรก)

  2. บริบทมีส่วนสำคัญในการคำนวณจำนวนบรรทัด ตัวอย่างเช่นหากความสูงของเส้นไม่ได้กำหนดไว้อย่างชัดเจนในลำดับชั้นขององค์ประกอบเป้าหมายคุณอาจได้รับ "ปกติ" กลับมาเป็นความสูงของเส้น นอกจากนี้องค์ประกอบอาจกำลังใช้งานอยู่box-sizing: border-boxดังนั้นจึงต้องมีช่องว่างภายใน

แนวทางของฉันลด # 2 โดยการควบคุมความสูงของเส้นโดยตรงและแยกตัวประกอบในวิธีการปรับขนาดกล่องซึ่งนำไปสู่ผลลัพธ์ที่กำหนดได้มากขึ้น


1

ในบางกรณีเช่นลิงก์ที่ทอดผ่านหลายแถวในข้อความที่ไม่เหมาะสมคุณจะได้รับจำนวนแถวและทุกพิกัดของแต่ละบรรทัดเมื่อคุณใช้สิ่งนี้:

var rectCollection = object.getClientRects();

https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects

วิธีนี้ใช้ได้ผลเพราะแต่ละบรรทัดจะแตกต่างกันเล็กน้อย ตราบใดที่พวกเขาวาดภาพเหล่านี้เป็น "สี่เหลี่ยมผืนผ้า" ที่แตกต่างกันโดยตัวแสดงผล


0

ทำตามคำแนะนำ @BobBrunius 2010 ฉันสร้างสิ่งนี้ด้วย jQuery ไม่ต้องสงสัยเลยว่ามันจะดีขึ้น แต่มันอาจช่วยได้บ้าง

$(document).ready(function() {

  alert("Number of lines: " + getTextLinesNum($("#textbox")));

});

function getTextLinesNum($element) {

  var originalHtml = $element.html();
  var words = originalHtml.split(" ");
  var linePositions = [];
        
  // Wrap words in spans
  for (var i in words) {
    words[i] = "<span>" + words[i] + "</span>";
  }
        
  // Temporarily replace element content with spans. Layout should be identical.
  $element.html(words.join(" "));
        
  // Iterate through words and collect positions of text lines
  $element.children("span").each(function () {
    var lp = $(this).position().top;
    if (linePositions.indexOf(lp) == -1) linePositions.push(lp);
  });
        
  // Revert to original html content
  $element.html(originalHtml);
        
  // Return number of text lines
  return linePositions.length;

}
#textbox {
  width: 200px;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="textbox">Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
  <br>sed diam nonummy</div>


0

คุณสามารถเปรียบเทียบความสูงขององค์ประกอบและความสูงขององค์ประกอบได้ line-height: 0

function lineCount(elm) {
  const style = elm.getAttribute('style')
  elm.style.marginTop = 0
  elm.style.marginBottom = 0
  elm.style.paddingTop = 0
  elm.style.paddingBottom = 0
  const heightAllLine = elm.offsetHeight
  elm.style.lineHeight = 0
  const height1line = elm.offsetHeight
  const lineCount = Math.round(heightAllLine / height1line)
  elm.setAttribute('style', style)
  if (isNaN(lineCount)) return 0
  return lineCount
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.