2011-09-16 28 views
18

Một vấn đề thường gặp khi làm việc với kiểu chữ trong HTML/CSS là thứ chúng tôi gọi là "horunge" bằng tiếng Thụy Điển ("widow" bằng tiếng Anh).JavaScript để tránh góa phụ

gì nó là:

Hãy nói rằng bạn có một hộp có chiều rộng 200px và với dòng chữ "Tôi yêu typograpy rất nhiều". Bây giờ vỡ văn bản và trở thành:

Tôi yêu typography rất
nhiều

Là một nhà thiết kế tôi không muốn một đứa con hoang từ (đơn từ/hàng). Nếu đây là một tài liệu/PDF vv Tôi sẽ phá vỡ từ trước rất và trông như thế này:

Tôi yêu typography
rất nhiều

mà trông đẹp hơn nhiều.

Tôi có thể giải quyết vấn đề này bằng quy tắc CSS hoặc bằng javascript không? Quy tắc nên để không bao giờ để một từ đứng trống trên một hàng.

Tôi biết nó có thể được giải quyết bằng cách thêm một <br /> nhưng đó không phải là một giải pháp mà làm việc với độ rộng năng động, nội dung thức ăn, bản dịch khác nhau, phông chữ trình duyệt vấn đề hiển thị, vv

Cập nhật (giải pháp) tôi giải quyết vấn đề của tôi với plugin jquery này: http://matthewlein.com/widowfix/

+0

Góa phụ ... Thư khốn ... Tôi yêu Thụy Điển! :) – rybo111

Trả lời

0

Ngoài ra còn có các thuộc tính mở rộng CSS và trẻ mồ côi: xem about.com article.

Không chắc về hỗ trợ trình duyệt ...

EDIT: thêm thông tin về thực hiện WebKit đây: https://bugs.webkit.org/buglist.cgi?quicksearch=orphans.

+0

Hai tài khoản này chỉ hoạt động để in http://www.w3.org/TR/CSS21/page.html#break-inside – c69

+0

@ c69 Bạn nói đúng. Có ai biết về bất kỳ kế hoạch nào để thêm nội dung này cho phương tiện không được phân trang không? Không thể tìm thấy bất kỳ thứ gì trên web. Nó sẽ là tuyệt vời để xem một số công cụ kiểu chữ như thế này (và dòng chảy và runaround) thực hiện cho phương tiện truyền thông màn hình. –

+0

http://www.w3.org/TR/css3-regions/#best-region-breaks - một số công cụ này hoạt động trong IE10 pp3, và cũng sẽ hoạt động trong WebKit mới. – c69

0

Tôi đã thực hiện một chút script here, với sự giúp đỡ của this function để tìm chiều cao dòng.

Nó chỉ là một cách tiếp cận, nó có thể hoặc có thể không hoạt động, không có thời gian để kiểm tra thông qua.

Hiện tại, text_element phải là đối tượng jQuery.

function avoidBastardWord(text_element) 
{ 
    var string = text_element.text(); 
    var parent = text_element.parent(); 
    var parent_width = parent.width(); 
    var parent_height = parent.height(); 

    // determine how many lines the text is split into 
    var lines = parent_height/getLineHeight(text_element.parent()[0]); 

    // if the text element width is less than the parent width, 
    // there may be a widow 
    if (text_element.width() < parent_width) 
    { 
     // find the last word of the entire text 
     var last_word = text_element.text().split(' ').pop(); 

     // remove it from our text, creating a temporary string 
     var temp_string = string.substring(0, string.length - last_word.length - 1); 

     // set the new one-word-less text string into our element 
     text_element.text(temp_string); 

     // check lines again with this new text with one word less 
     var new_lines = parent.height()/getLineHeight(text_element.parent()[0]); 

     // if now there are less lines, it means that word was a widow 
     if (new_lines != lines) 
     { 
      // separate each word 
      temp_string = string.split(' '); 

      // put a space before the second word from the last 
      // (the one before the widow word) 
      temp_string[ temp_string.length - 2 ] = '<br>' + temp_string[ temp_string.length - 2 ] ; 

      // recreate the string again 
      temp_string = temp_string.join(' '); 

      // our element html becomes the string 
      text_element.html(temp_string); 
     } 
     else 
     { 
      // put back the original text into the element 
      text_element.text(string); 
     } 

    } 

} 

Các trình duyệt khác nhau có cài đặt phông chữ khác nhau. Cố gắng chơi một chút để thấy sự khác biệt. Tôi đã thử nghiệm nó trên IE8 và Opera, sửa đổi chuỗi mỗi lần và nó dường như làm việc ok.

Tôi muốn nghe một số phản hồi và cải thiện vì tôi cho rằng nó có thể hữu ích.

Chỉ chơi với nó! :)

0

thủ, bạn có thể thay thế các khoảng trống ở giữa với &nbsp;

Tôi đã tìm cách để tự động thêm nó vào.Tôi tìm thấy một vài, nhưng đã không thể làm cho nó làm việc bản thân mình.

+0

phải có "& n b s p;" (không có khoảng trống ở giữa, & không gian trống) – matt

+0

mã bọc giữa hai biểu tượng 'để cho phép định dạng thích hợp – Luca

6

Một giải pháp jQuery/regrex đơn giản có thể trông giống như sau, nếu bạn thêm lớp "noWidows" vào thẻ của bất kỳ phần tử nào có chứa văn bản bạn đang lo lắng.

Chẳng hạn như:

<p class="noWidows">This is a very important body of text.</p> 

Và sau đó sử dụng kịch bản này:

$('.noWidows').each(function(i,d){ 
    $(d).html($(d).text().replace(/\s(?=[^\s]*$)/g, "&nbsp;")) 
}); 

này sử dụng regex để tìm và thay thế khoảng trống cuối cùng trong chuỗi với một nhân vật không bị phá hủy. Có nghĩa là hai từ cuối cùng sẽ bị buộc vào cùng một dòng. Đó là một giải pháp tốt nếu bạn có khoảng trống ở cuối dòng vì điều này có thể làm cho văn bản chạy bên ngoài phần tử có chiều rộng cố định hoặc nếu không cố định, làm cho phần tử trở nên lớn hơn.

+0

Sẽ thật tuyệt nếu điều này không phá vỡ html bên trong các phần tử đã nói. – ShayneStatzell

2

Chỉ muốn thêm vào trang này vì nó đã giúp tôi rất nhiều.

Nếu bạn có (góa phụ) thực sự nên là trẻ mồ côi vì góa phụ là những từ đơn lẻ nằm trên trang tiếp theo chứ không phải những từ đơn lẻ trên một dòng mới.

Làm việc với các mã bưu điện như "N12 5GG" sẽ dẫn đến mã bưu chính đầy đủ nằm trên một dòng mới cùng nhau nhưng vẫn được phân loại là trẻ mồ côi để làm việc xung quanh. (Thay đổi lớp để "noWidow2", do đó bạn có thể sử dụng cả hai phiên bản.

123 Some_road, Some_town, N12 5gg

$('.noWidows2').each(function(i,d){ 
    var value="&nbsp;" 
    $(d).html($(d).text().replace(/\s(?=[^\s]*$)/g, value).replace(/\s(?=[^\s]*$)/g, value)); 
}); 

này sẽ cho kết quả là 3 không gian trắng cuối cùng là trên một dòng mới cùng nhau làm cho việc phát hành mã bưu điện.

End Result

123 Some_road, 
Some_town, N12 5GG 
0

$('span').each(function() { 
 
    var w = this.textContent.split(" "); 
 
    if (w.length > 1) { 
 
    w[w.length - 2] += "&nbsp;" + w[w.length - 1]; 
 
    w.pop(); 
 
    this.innerHTML = (w.join(" ")); 
 
    } 
 
});
#foo { 
 
    width: 124px; 
 
    border: 1px solid #ccc; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="foo"> 
 
    <span class="orphan">hello there I am a string really really long, I wonder how many lines I have</span> 
 
</div>

Các vấn đề liên quan