Javascript 很好地截断字符串以适合给定的像素宽度

Javascript 很好地截断字符串以适合给定的像素宽度,javascript,text,reference,refactoring,Javascript,Text,Reference,Refactoring,有时,字符串必须适合某个像素宽度。此函数尝试有效地执行此操作。请在下面发布您的建议或重构:) 函数fitStringToSize(str,len){ var-shortStr=str; var f=document.createElement(“span”); f、 style.display='隐藏'; f、 style.padding='0px'; 文件.正文.附件(f); //在第一次运行时,检查字符串是否已经适合长度。 f、 innerHTML=str; 差异=f.偏移网络宽度-长度;

有时,字符串必须适合某个像素宽度。此函数尝试有效地执行此操作。请在下面发布您的建议或重构:)

函数fitStringToSize(str,len){
var-shortStr=str;
var f=document.createElement(“span”);
f、 style.display='隐藏';
f、 style.padding='0px';
文件.正文.附件(f);
//在第一次运行时,检查字符串是否已经适合长度。
f、 innerHTML=str;
差异=f.偏移网络宽度-长度;
//如果字符串太长,请将其缩短大约
//字符差异(减少迭代次数)。
而(差异>0)
{
shortStr=substring(str,0,(str.length-Math.ceil(diff/5))+'…';
f、 innerHTML=shortStr;
差异=f.偏移网络宽度-长度;
}
while(f.lastChild){
f、 removeChild(f.lastChild);
}
文件.正文.删除儿童(f);
//如果字符串太长,请放入原始字符串
//在缩写的title元素中,并附加省略号
if(短长度<短长度)
{

return';请随意使用fork并提交修补程序:)

快速浏览一下,我觉得不错。以下是一些小建议:

  • 使用二进制搜索查找最佳大小,而不是线性搜索

  • (可选)添加鼠标悬停,以便工具提示显示完整字符串


    • 您的代码有几个问题

      • 为什么
        /5
        ?字符的宽度取决于
        字体系列
        字体大小
      • 您必须在缩写标题中转义
        str
        (否则“将使代码无效”)
      • diff
        未声明,并以全局范围结束
      • 子字符串
        不应该这样工作。您使用的浏览器是什么
      • hidden
        不是有效的
        样式值。请显示
        。要隐藏它,您应该使用值
        none
        ,但浏览器不会计算
        偏移宽度
        。请改用
        style.visibility=“hidden”
      • 搜索正确的长度是非常低效的
      • 必须转义
        /abbr
      我为您重新编写了它,并添加了
      className
      ,这样您就可以使用样式来设置
      font-family
      font-size
      。Fooz先生建议您使用鼠标盖来显示整个字符串。这是不必要的,因为现代浏览器可以为您这样做(使用FF、IE、Opera和Chrome进行测试)


      你能写同样的函数,但要适合div的宽度和高度吗?我有一个固定宽度和高度的div,我需要把数据库中的文本放在这里。如果文本对div来说太大,我想剪切它,并在最后添加广告…可能吗?谢谢

      编辑: 我为我的问题找到了JS解决方案:

      <p id="truncateMe">Lorem ipsum dolor sit amet, consectetuer adipiscing
      elit. Aenean consectetuer. Etiam venenatis. Sed ultricies, pede sit
      amet aliquet lobortis, nisi ante sagittis sapien, in rhoncus lectus
      mauris quis massa. Integer porttitor, mi sit amet viverra faucibus,
      urna libero viverra nibh, sed dictum nisi mi et diam. Nulla nunc eros,
      convallis sed, varius ac, commodo et, magna. Proin vel
      risus. Vestibulum eu urna. Maecenas lobortis, pede ac dictum pulvinar,
      nibh ante vestibulum tortor, eget fermentum urna ipsum ac neque. Nam
      urna nulla, mollis blandit, pretium id, tristique vitae, neque. Etiam
      id tellus. Sed pharetra enim non nisl.</p>
      
      <script type="text/javascript">
      
      var len = 100;
      var p = document.getElementById('truncateMe');
      if (p) {
      
        var trunc = p.innerHTML;
        if (trunc.length > len) {
      
          /* Truncate the content of the P, then go back to the end of the
             previous word to ensure that we don't truncate in the middle of
             a word */
          trunc = trunc.substring(0, len);
          trunc = trunc.replace(/\w+$/, '');
      
          /* Add an ellipses to the end and make it a link that expands
             the paragraph back to its original size */
          trunc += '<a href="#" ' +
            'onclick="this.parentNode.innerHTML=' +
            'unescape(\''+escape(p.innerHTML)+'\');return false;">' +
            '...<\/a>';
          p.innerHTML = trunc;
        }
      }
      
      </script>
      

      Lorem ipsum door sit amet,继续前进 elit.Aenean Concertetuer.Etiam venenatis.Sed ultricies,pede sit 阿梅特·阿利奎特·洛博蒂斯,前矢状面尼西,右后角 毛里斯·奎斯·马萨,整数港口,我是艾米特·维韦拉·福西布斯, 我们的自由生活在尼布,这是一句名言:我的爱和我的心不属于爱欲, 康瓦利斯塞德,华力士ac,康莫多等,麦格纳。普罗因级别 前庭,前庭,前庭,前庭,前庭,前庭, 前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭前庭 乌尔纳·努拉,莫利斯·布兰迪特,普雷蒂姆·艾迪姆,崔斯蒂克·维塔,内克·艾蒂安 我告诉你,这是一种非nisl的药物

      var-len=100; var p=document.getElementById('truncateMe'); 如果(p){ var trunc=p.innerHTML; 如果(实际长度>长度){ /*截断P的内容,然后返回到 前一个字,以确保我们不截断中间 一句话*/ trunc=trunc.子串(0,len); trunc=trunc.replace(/\w+$/,“”); /*在末尾添加一个椭圆,使其成为展开的链接 段落恢复到原来的大小*/ trunc+=''+ '...'; p、 innerHTML=trunc; } }
      出于我的目的,我删除了…中的链接,因为我的页面上有另一个选项卡,可以保存完整的文本。

      幸运的是,我最终应该处理好这个问题

      如果有人正在使用ASP.NET并对服务器端解决方案感兴趣,请查看以下博文:


      title属性将在所有现代浏览器中提供鼠标悬停工具提示:)当你说二进制搜索时,你是什么意思?现在它试图将字符串缩短到超长的估计字符数,因此无论字符串有多长,它应该只有1-3次迭代非常好,谢谢你。/5是基于眼睛选择的在我的应用程序中使用它(m是10px,f是3px)这实际上是一种垃圾,因为字体大小会根据字符串将要放入的div的样式而变化,所以理想情况下我们不会附加到body,而是附加到该div。substring:gah,我认为这是一个输入错误,忘记了range start操作符。如果要插入sting的元素在e dom,您可以修改上面的函数以将其插入其中。但是,如果该元素具有style.display=“none”则不会获得宽度…使用body和类名毕竟不是一个坏主意。我还添加了.replace(/(\s.)?\s*$/,“”)到结果赋值中,以消除尾随空格或寡居的单个字符。您可以发布一个使用这种方法的示例吗?例如,JSFIDLE
          function fitStringToSize(str,len,className) {
          var result = str; // set the result to the whole string as default
          var span = document.createElement("span");
          span.className=className; //Allow a classname to be set to get the right font-size.
          span.style.visibility = 'hidden';
          span.style.padding = '0px';
          document.body.appendChild(span);
      
      
          // check if the string don't fit 
          span.innerHTML = result;
          if (span.offsetWidth > len) {
              var posStart = 0, posMid, posEnd = str.length;
              while (true) {
                  // Calculate the middle position
                  posMid = posStart + Math.ceil((posEnd - posStart) / 2);
                  // Break the loop if this is the last round
                  if (posMid==posEnd || posMid==posStart) break;
      
                  span.innerHTML = str.substring(0,posMid) + '&hellip;';
      
                  // Test if the width at the middle position is
                  // too wide (set new end) or too narrow (set new start).
                  if ( span.offsetWidth > len ) posEnd = posMid; else posStart=posMid;
              }
              //Escape
              var title = str.replace("\"","&#34;");
              //Escape < and >
              var body = str.substring(0,posStart).replace("<","&lt;").replace(">","&gt;");
              result = '<abbr title="' + title + '">' + body + '&hellip;<\/abbr>';
          }
          document.body.removeChild(span);
          return result;
          }
      
      function fitStringToWidth(str,width,className) {
        // str    A string where html-entities are allowed but no tags.
        // width  The maximum allowed width in pixels
        // className  A CSS class name with the desired font-name and font-size. (optional)
        // ----
        // _escTag is a helper to escape 'less than' and 'greater than'
        function _escTag(s){ return s.replace("<","&lt;").replace(">","&gt;");}
      
        //Create a span element that will be used to get the width
        var span = document.createElement("span");
        //Allow a classname to be set to get the right font-size.
        if (className) span.className=className;
        span.style.display='inline';
        span.style.visibility = 'hidden';
        span.style.padding = '0px';
        document.body.appendChild(span);
      
        var result = _escTag(str); // default to the whole string
        span.innerHTML = result;
        // Check if the string will fit in the allowed width. NOTE: if the width
        // can't be determined (offsetWidth==0) the whole string will be returned.
        if (span.offsetWidth > width) {
          var posStart = 0, posMid, posEnd = str.length, posLength;
          // Calculate (posEnd - posStart) integer division by 2 and
          // assign it to posLength. Repeat until posLength is zero.
          while (posLength = (posEnd - posStart) >> 1) {
            posMid = posStart + posLength;
            //Get the string from the beginning up to posMid;
            span.innerHTML = _escTag(str.substring(0,posMid)) + '&hellip;';
      
            // Check if the current width is too wide (set new end)
            // or too narrow (set new start)
            if ( span.offsetWidth > width ) posEnd = posMid; else posStart=posMid;
          }
      
          result = '<abbr title="' +
            str.replace("\"","&quot;") + '">' +
            _escTag(str.substring(0,posStart)) +
            '&hellip;<\/abbr>';
        }
        document.body.removeChild(span);
        return result;
      }
      
      <p id="truncateMe">Lorem ipsum dolor sit amet, consectetuer adipiscing
      elit. Aenean consectetuer. Etiam venenatis. Sed ultricies, pede sit
      amet aliquet lobortis, nisi ante sagittis sapien, in rhoncus lectus
      mauris quis massa. Integer porttitor, mi sit amet viverra faucibus,
      urna libero viverra nibh, sed dictum nisi mi et diam. Nulla nunc eros,
      convallis sed, varius ac, commodo et, magna. Proin vel
      risus. Vestibulum eu urna. Maecenas lobortis, pede ac dictum pulvinar,
      nibh ante vestibulum tortor, eget fermentum urna ipsum ac neque. Nam
      urna nulla, mollis blandit, pretium id, tristique vitae, neque. Etiam
      id tellus. Sed pharetra enim non nisl.</p>
      
      <script type="text/javascript">
      
      var len = 100;
      var p = document.getElementById('truncateMe');
      if (p) {
      
        var trunc = p.innerHTML;
        if (trunc.length > len) {
      
          /* Truncate the content of the P, then go back to the end of the
             previous word to ensure that we don't truncate in the middle of
             a word */
          trunc = trunc.substring(0, len);
          trunc = trunc.replace(/\w+$/, '');
      
          /* Add an ellipses to the end and make it a link that expands
             the paragraph back to its original size */
          trunc += '<a href="#" ' +
            'onclick="this.parentNode.innerHTML=' +
            'unescape(\''+escape(p.innerHTML)+'\');return false;">' +
            '...<\/a>';
          p.innerHTML = trunc;
        }
      }
      
      </script>