JS / jQuery: Попытка вписать произвольную текстовую строку в пределах определенной ширины через substr - PullRequest
1 голос
/ 26 марта 2010

Я пытаюсь взять текстовую строку (например, слово «тестирование») и вычислить, будет ли строка при отображении на экране превышать определенную ширину. Я делаю это, помещая его в элемент и используя width ().

Теперь я хочу уменьшить текстовую строку на символ за раз, а затем определить ширину. Если ширина в пределах скажем "130px", то я верну эту усеченную строку. У меня есть следующая рекурсивная функция, но я новичок в Js / jQuery и не уверен, что я сделал неправильно. Если определено, что строка требует усечения, функция возвращает неопределенное значение.

Любая помощь очень ценится. Большое спасибо!

  function fitWidth(str) {
    var width = $('span.width').html(str).width();
    if (width > '130') {
      strlength = str.length-1;
      str = str.substr(0,strlength);
      fitWidth(str);
    } else {
      return str; // something wrong here?
    }
  }

var testStr = 'Lorem Ipsum';
alert(fitWidth(testStr)); // returns undefined if it was truncated

если str требует усечения, fitWidth () вернет "undefined"

Ответы [ 4 ]

2 голосов
/ 26 марта 2010

Вы должны сказать return fitWidth(str); в рекурсивном случае.

0 голосов
/ 05 апреля 2014

Я изменил код операции, чтобы он работал для меня.

Это использует jQuery и требует, чтобы вы добавили эту функцию (заканчивается) в прототип String. Смотри https://stackoverflow.com/a/2548133/80353.

    function fitWidth(str, selector, widthLimit, heightLimit, suffix, original) {
        if (typeof heightLimit == 'undefined') {
            heightLimit = 10000000000;
        }
        if (typeof suffix == 'undefined') {
            suffix = '';
        }
        if (typeof original == 'undefined') {
            original = str;
        }
        if (suffix.length > 0 && str.endsWith(suffix)) {
            str = str.substr(0, str.length - suffix.length);
        }
        var width = $(selector).html(str).width();
        var height = $(selector).html(str).height();
        if (suffix.length > 0 && original != str) {
            var width = $(selector).html(str + suffix).width();
            var height = $(selector).html(str + suffix).height();
        }

        // console.info($(selector));
        // console.info(width);
        if (width > widthLimit || height > heightLimit) {
          strlength = str.length-1;
          str = str.substr(0,strlength);
          $(selector).html(str + suffix);
          fitWidth(str + suffix, selector, widthLimit, heightLimit, suffix, original);
        } else {
          return true;
        }
      }

// if you want to consider suffix for shortened content like "I want to ..."
fixWidth("I want to break free", "#selector", 180, 60, " ...");

Надеюсь, это поможет другим.

0 голосов
/ 26 марта 2010

// Вот еще один метод,

// но вам нужно перевести его на jquery-

function truncate(str, w, pa){
    if(!pa) pa= document.body;
    w= w || pa.offsetWidth;
    var wid, t, L= str.length, c= document.createElement('div');
    c.style.cssText= 
    'position:absolute; visibility:hidden; font:inherit; white-space:pre';
    t= document.createTextNode(str);
    c.appendChild(t);
    pa.appendChild(c);
    wid= c.offsetWidth;

    if(w< wid){
        L= Math.floor(L*(w/wid))-1;
        t.data= str= str.substring(0, L);
        while(t.data && c.offsetWidth> w){
            t.data= str= str.slice(0, -1);
        }
    }
    pa.removeChild(c);
    return str;
}
var testStr= 'The style is white-space:pre to keep it on one line';
alert(truncate(testStr, 130));


//comments
function truncate(str, w, pa){
    // create a hidden element to measure the text-
    // pass a parent element (pa) if the target's font family,
    // weight or size is not the same as body text
    // or if you use the parent's width to size the text

    if(!pa) pa= document.body;
    w= w || pa.offsetWidth;
    var wid, t, L= str.length, c= document.createElement('div');
    c.style.cssText= 
    'position:absolute;visibility:hidden;font:inherit;white-space:pre';
    t= document.createTextNode(str);
    c.appendChild(t);
    pa.appendChild(c);
    wid= c.offsetWidth;

    // measure the width of the whole string
    // if it fits your width, skip the calculations,
    // otherwise multiply the length of the string by
    // the width you want divided by the actual width

    if(w< wid){
        L= Math.floor(L*(w/wid))-1;
        //I'd subtract 1 to grow on and call it str.substring(0, L);

        //but if the exact to the pixel width is critical,
        //measure the new string and chop it if it still needs it:

        t.data= str= str.substring(0, L);
        while(t.data && c.offsetWidth> w){
            t.data= str= str.slice(0, -1);
        }
    }
    // clean up, and return the (possibly) shortened string

    pa.removeChild(c);
    return str;
}
0 голосов
/ 26 марта 2010

Новый ответ: Я не знаю, будет ли это быстрее, но это работает.

function fitWidth(str) {
  var width = $('span.width').css('display', 'inline').html(str).width();
  var charWidth = Math.round(width / str.length);
  var maxLength = 130 / charWidth;
  $('span.width').html(str.substr(0, maxLength));
}

Старый ответ:

вместо того, чтобы делать это рекурсивно, почему бы вам просто не использовать substr (), чтобы сделать ширину 130.

вроде так:

function fitWidth(str) {
  var width = $('span.width').html(str).width();
  if(width > 130) {
    return str.substr(0, 130);
  } else {
    return str; 
  }
}

EDIT: о, теперь я вижу, что вы говорите о ширине против длины символов в строке. Тем не менее, если вы берете ширину используемого шрифта, я думаю, что вы все равно можете избежать нескольких шагов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...