web-dev-qa-db-ja.com

コンテンツが広すぎる場合は、HTMLタグに省略記号(...)を挿入します

ブラウザウィンドウのサイズを変更すると幅が変わる伸縮性のあるレイアウトのWebページがあります。

このレイアウトには、可変長の見出し(h2)があります(実際には、私が制御できないブログ投稿の見出しです)。現在、ウィンドウよりも幅が広い場合、2行に分割されます。

たとえばjQueryを使用して、その見出しタグのinnerHTMLを短縮し、テキストが現在の画面の1行に収まらない場合は「...」を追加するエレガントでテスト済みの(クロスブラウザ)ソリューションがありますかコンテナ幅?

144
BlaM

FF3、Safari、IE6 +で単一行および複数行のテキストを使用するソリューションがあります

.Ellipsis {
    white-space: nowrap;
    overflow: hidden;
}

.Ellipsis.multiline {
    white-space: normal;
}

<div class="Ellipsis" style="width: 100px; border: 1px solid black;">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
<div class="Ellipsis multiline" style="width: 100px; height: 40px; border: 1px solid black; margin-bottom: 100px">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>

<script type="text/javascript" src="/js/jquery.Ellipsis.js"></script>
<script type="text/javascript">
$(".Ellipsis").Ellipsis();
</script>

jquery.Ellipsis.js

(function($) {
    $.fn.Ellipsis = function()
    {
        return this.each(function()
        {
            var el = $(this);

            if(el.css("overflow") == "hidden")
            {
                var text = el.html();
                var multiline = el.hasClass('multiline');
                var t = $(this.cloneNode(true))
                    .hide()
                    .css('position', 'absolute')
                    .css('overflow', 'visible')
                    .width(multiline ? el.width() : 'auto')
                    .height(multiline ? 'auto' : el.height())
                    ;

                el.after(t);

                function height() { return t.height() > el.height(); };
                function width() { return t.width() > el.width(); };

                var func = multiline ? height : width;

                while (text.length > 0 && func())
                {
                    text = text.substr(0, text.length - 1);
                    t.html(text + "...");
                }

                el.html(t.html());
                t.remove();
            }
        });
    };
})(jQuery);
118
alex

次のCSSのみのソリューションは、Firefox 6.0を除き、執筆時点で http://www.caniuse.com にリストされているすべてのブラウザで1行のテキストを切り捨てます。 JavaScriptは、複数行テキストの折り返しやFirefoxの以前のバージョンをサポートする必要がない限り、まったく不要です。

.Ellipsis {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: Ellipsis;
    -o-text-overflow: Ellipsis;
}

Firefoxの以前のバージョンのサポートが必要な場合は、 この他の質問に対する私の答え をご覧ください。

179
Simon Lieschke

他の多くの投稿を使用してこのコードを作成し、次の機能強化を行いました。

  1. バイナリ検索を使用して、適切なテキスト長を見つけます。
  2. アイテムが最初に表示されたときにEllipsisコードを再実行するワンショットショーイベントを設定することにより、Ellipsis要素が最初に非表示になっているケースを処理します。これは、一部の項目が最初に表示されないマスター詳細ビューまたはツリービューに便利です。
  3. オプションで、ホバーオーバー効果の元のテキストにタイトル属性を追加します。
  4. display: blockをスタイルに追加したため、スパンが機能します
  5. 3つのピリオドの代わりに省略記号文字を使用します。
  6. .Ellipsisクラスを使用して、スクリプトを自動実行します

CSS:

.Ellipsis {
        white-space: nowrap;
        overflow: hidden;
        display: block;
}

.Ellipsis.multiline {
        white-space: normal;
}

jquery.Ellipsis.js

(function ($) {

    // this is a binary search that operates via a function
    // func should return < 0 if it should search smaller values
    // func should return > 0 if it should search larger values
    // func should return = 0 if the exact value is found
    // Note: this function handles multiple matches and will return the last match
    // this returns -1 if no match is found
    function binarySearch(length, func) {
        var low = 0;
        var high = length - 1;
        var best = -1;
        var mid;

        while (low <= high) {
            mid = ~ ~((low + high) / 2); //~~ is a fast way to convert something to an int
            var result = func(mid);
            if (result < 0) {
                high = mid - 1;
            } else if (result > 0) {
                low = mid + 1;
            } else {
                best = mid;
                low = mid + 1;
            }
        }

        return best;
    }

    // setup handlers for events for show/hide
    $.each(["show", "toggleClass", "addClass", "removeClass"], function () {

        //get the old function, e.g. $.fn.show   or $.fn.hide
        var oldFn = $.fn[this];
        $.fn[this] = function () {

            // get the items that are currently hidden
            var hidden = this.find(":hidden").add(this.filter(":hidden"));

            // run the original function
            var result = oldFn.apply(this, arguments);

            // for all of the hidden elements that are now visible
            hidden.filter(":visible").each(function () {
                // trigger the show msg
                $(this).triggerHandler("show");
            });

            return result;
        };
    });

    // create the Ellipsis function
    // when addTooltip = true, add a title attribute with the original text
    $.fn.Ellipsis = function (addTooltip) {

        return this.each(function () {
            var el = $(this);

            if (el.is(":visible")) {

                if (el.css("overflow") === "hidden") {
                    var content = el.html();
                    var multiline = el.hasClass('multiline');
                    var tempElement = $(this.cloneNode(true))
                        .hide()
                        .css('position', 'absolute')
                        .css('overflow', 'visible')
                        .width(multiline ? el.width() : 'auto')
                        .height(multiline ? 'auto' : el.height())
                    ;

                    el.after(tempElement);

                    var tooTallFunc = function () {
                        return tempElement.height() > el.height();
                    };

                    var tooWideFunc = function () {
                        return tempElement.width() > el.width();
                    };

                    var tooLongFunc = multiline ? tooTallFunc : tooWideFunc;

                    // if the element is too long...
                    if (tooLongFunc()) {

                        var tooltipText = null;
                        // if a tooltip was requested...
                        if (addTooltip) {
                            // trim leading/trailing whitespace
                            // and consolidate internal whitespace to a single space
                            tooltipText = $.trim(el.text()).replace(/\s\s+/g, ' ');
                        }

                        var originalContent = content;

                        var createContentFunc = function (i) {
                            content = originalContent.substr(0, i);
                            tempElement.html(content + "…");
                        };

                        var searchFunc = function (i) {
                            createContentFunc(i);
                            if (tooLongFunc()) {
                                return -1;
                            }
                            return 0;
                        };

                        var len = binarySearch(content.length - 1, searchFunc);

                        createContentFunc(len);

                        el.html(tempElement.html());

                        // add the tooltip if appropriate
                        if (tooltipText !== null) {
                            el.attr('title', tooltipText);
                        }
                    }

                    tempElement.remove();
                }
            }
            else {
                // if this isn't visible, then hook up the show event
                el.one('show', function () {
                    $(this).Ellipsis(addTooltip);
                });
            }
        });
    };

    // ellipsification for items with an Ellipsis
    $(document).ready(function () {
        $('.Ellipsis').Ellipsis(true);
    });

} (jQuery));
39
Adam Tegen

私の答えは単一行のテキストのみをサポートしています。複数行の分岐については、gfullamの以下のコメントを確認してください。かなり有望です。

最初の回答のコードを何度か書き直しましたが、これが最速だと思います。

最初に「推定」テキストの長さを見つけてから、幅が正しくなるまで文字を追加または削除します。

使用するロジックは次のとおりです。

enter image description here

「推定」テキストの長さが見つかった後、希望の幅に達するまで文字が追加または削除されます。

微調整が必​​要なはずですが、コードは次のとおりです。

(function ($) {
    $.fn.Ellipsis = function () {
        return this.each(function () {
            var el = $(this);

            if (el.css("overflow") == "hidden") {
                var text = el.html().trim();
                var t = $(this.cloneNode(true))
                                        .hide()
                                        .css('position', 'absolute')
                                        .css('overflow', 'visible')
                                        .width('auto')
                                        .height(el.height())
                                        ;
                el.after(t);

                function width() { return t.width() > el.width(); };

                if (width()) {

                    var myElipse = "....";

                    t.html(text);

                    var suggestedCharLength = (text.length * el.width() / t.width()) - myElipse.length;

                    t.html(text.substr(0, suggestedCharLength) + myElipse);

                    var x = 1;
                    if (width()) {
                        while (width()) {
                            t.html(text.substr(0, suggestedCharLength - x) + myElipse);
                            x++;
                        }
                    }
                    else {
                        while (!width()) {
                            t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                            x++;
                        }
                        x--;
                        t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                    }

                    el.html(t.html());
                    t.remove();
                }
            }
        });
    };
})(jQuery);
20
Mikey G

テキストのすべての種類の省略記号を処理するための本当にクールなjQueryプラグインを作成しました。ThreeDots@ http://tpgblog.com/threedots

CSSアプローチよりもはるかに柔軟性があり、はるかに高度でカスタマイズ可能な動作と相互作用をサポートします。

楽しい。

18
Jeremy Horn

Y'allが2013年にここで終わる場合に備えて-ここに私が見つけた純粋なCSSアプローチがあります: http://css-tricks.com/snippets/css/truncate-string-with-Ellipsis/ =

.truncate {
  width: 250px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: Ellipsis;
}

うまくいきます。

18
Joseph Juhnke

Ellipsisの後の要素(「read-more」ボタンなど)を保持し、onWindowResizeを更新できる、より柔軟なjQueryプラグイン。また、マークアップを使用してテキストを回避します。

http://dotdotdot.frebsite.nl

8
Matt

trunk8 jQueryプラグインは複数行をサポートし、省略記号の接尾辞には省略記号だけでなく任意のhtmlを使用できます。 https://github.com/rviscomi/trunk8

デモはこちら: http://jrvis.com/trunk8/

8
Eliot Sykes

CSSでこれを行う IEがこれを非標準で拡張し、FFが:afterをサポートするという事実を利用するための実際の非常に簡単な方法があります。

JSでこれを行う 必要に応じて、ターゲットのscrollWidthを調べて、それを親の幅と比較することもできますが、これは堅牢ではありません。

編集:これは明らかに思ったよりも開発されています。 CSS3のサポートはまもなく存在する可能性があり、いくつかの不完全な拡張機能を試してみることができます。

最後の1つは良い読書です。

5
annakata

さて、「...」はまったく追加されませんが、<h2>が2行に分割されるのを防ぐ簡単な解決策の1つは、次のcssを追加することです。

h2 {
    height:some_height_in_px; /* this is the height of the line */
    overflow:hidden; /* so that the second (or third, fourth, etc.)
                        line is not visible */
}

私はそれをもう少し考えて、この解決策を思いつきました、あなたはあなたのh2タグのテキストコンテンツを別のタグ(例えばスパン)でラップする必要がありますこの種のjavascriptを使用して、不要な単語を除外できます。

var elems = document.getElementById('conainter_of_h2s').
                     getElementsByTagName('h2');

    for ( var i = 0, l = elems.length; i < l; i++) {
        var span = elems.item(i).getElementsByTagName('span')[0];
        if ( span.offsetHeight > elems.item(i).offsetHeight ) {
            var text_arr = span.innerHTML.split(' ');
            for ( var j = text_arr.length - 1; j>0 ; j--) {
                delete text_arr[j];
                span.innerHTML = text_arr.join(' ') + '...';
                if ( span.offsetHeight <= 
                                        elems.item(i).offsetHeight ){
                    break;
                }
            }
        }
    }
3
Ramuns Usovs

テキストコンテンツ用の純粋なCSS複数行省略記号:

.container{
    position: relative;  /* Essential */
    background-color: #bbb;  /* Essential */
    padding: 20px; /* Arbritrary */
}
.text {
    overflow: hidden;  /* Essential */
    /*text-overflow: Ellipsis; Not needed */
    line-height: 16px;  /* Essential */
    max-height: 48px; /* Multiples of line-height */
}
.Ellipsis {
    position: absolute;/* Relies on relative container */
    bottom: 20px; /* Matches container padding */
    right: 20px; /* Matches container padding */
    height: 16px; /* Matches line height */
    width: 30px; /* Arbritrary */
    background-color: inherit; /* Essential...or specify a color */
    padding-left: 8px; /* Arbritrary */
}
<div class="container">
    <div class="text">
        Lorem ipsum dolor sit amet, consectetur eu in adipiscing elit. Aliquam consectetur venenatis blandit. Praesent vehicula, libero non pretium vulputate, lacus arcu facilisis lectus, sed feugiat tellus nulla eu dolor. Nulla porta bibendum lectus quis euismod. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat.
    </div>
    <div class="Ellipsis">...</div>
</div>

実際の例については、スニペットをご覧ください。

3
Jason Williams

別のJavaScriptソリューションを次に示します。非常に良好で非常に高速に動作します。

https://github.com/dobiatowski/jQuery.FastEllipsis

WindowsおよびMac上のChrome、FF、IEでテスト済み。

3
Adam Lukaszczyk

純粋なCSSを使用した複数行テキスト用のソリューションがあります。 line-clampと呼ばれますが、Webkitブラウザーでのみ機能します。ただし、最新のすべてのブラウザー(IE8よりも新しいものすべて)でこれを模倣する方法があります。また、最後の行の最後の単語を隠すには背景画像が必要なので、単色の背景でのみ動作します。方法は次のとおりです。

このHTMLを考えると:

<p class="example" id="example-1">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

CSSは次のとおりです。

p {
    position:relative;
    line-height:1.4em;
    height:4.2em;      /* 3 times the line-height to show 3 lines */
}
p::after {
    content:"...";
    font-weight:bold;
    position:absolute;
    bottom:0;
    right:0;
    padding:0 20px 1px 45px;
    background:url(Ellipsis_bg.png) repeat-y;
}

Ellipsis_bg.pngは、背景と同じ色の画像です。幅は約100ピクセルで、行の高さと同じ高さになります。

テキストは文字の途中で切り取られる可能性があるため、あまりきれいではありませんが、場合によっては便利です。

リファレンス: http://www.css-101.org/articles/line-clamp/line-clamp_for_non_webkit-based_browsers.php

3
Jules Colle

最近、クライアントのために似たようなことをしました。ここに私が彼らのためにしたことのバージョンがあります(Win Vistaのすべての最新ブラウザーバージョンでテストされた例)。全面的に完璧ではありませんが、かなり簡単に調整できます。

デモ: http://enobrev.info/Ellipsis/

コード:

<html>
    <head>
        <script src="http://www.google.com/jsapi"></script>
        <script>            
            google.load("jquery", "1.2.6");
            google.setOnLoadCallback(function() {
                $('.longtext').each(function() {
                    if ($(this).attr('scrollWidth') > $(this).width()) {
                        $more = $('<b class="more">&hellip;</b>');

                        // add it to the dom first, so it will have dimensions
                        $(this).append($more);

                        // now set the position
                        $more.css({
                            top: '-' + $(this).height() + 'px',
                            left: ($(this).attr('offsetWidth') - $more.attr('offsetWidth')) + 'px'
                        });
                    }
                });
            });
        </script>

        <style>
            .longtext {
                height: 20px;
                width: 300px;
                overflow: hidden;
                white-space: nowrap;
                border: 1px solid #f00;
            }

            .more {
                z-index: 10;
                position: relative;
                display: block;
                background-color: #fff;
                width: 18px;
                padding: 0 2px;
            }
        </style>
    </head>
    <body>
        <p class="longtext">This is some really long text.  This is some really long text.  This is some really long text.  This is some really long text.</p>
    </body>
</html>
3
enobrev

これはAlexに似ていますが、線形ではなくログ時間で行い、maxHeightパラメーターを取ります。

jQuery.fn.Ellipsis = function(text, maxHeight) {
  var element = $(this);
  var characters = text.length;
  var step = text.length / 2;
  var newText = text;
  while (step > 0) {
    element.html(newText);
    if (element.outerHeight() <= maxHeight) {
      if (text.length == newText.length) {
        step = 0;
      } else {
        characters += step;
        newText = text.substring(0, characters);
      }
    } else {
      characters -= step;
      newText = newText.substring(0, characters);
    }
    step = parseInt(step / 2);
  }
  if (text.length > newText.length) {
    element.html(newText + "...");
    while (element.outerHeight() > maxHeight && newText.length >= 1) {
      newText = newText.substring(0, newText.length - 1);
      element.html(newText + "...");
    }
  }
};
2

Devon Govett によるシンプルなjQueryソリューションがあります:

https://Gist.github.com/digulla/5796047

使用するには、jQueryオブジェクトでEllipsis()を呼び出すだけです。例えば:

$( "span")。Ellipsis();

2
BlaM

Alexの関数をMooToolsライブラリに使用するように書き直しました。 Wordの途中で省略記号を追加するのではなく、Wordジャンプに少し変更しました。

Element.implement({
Ellipsis: function() {
    if(this.getStyle("overflow") == "hidden") {
        var text = this.get('html');
        var multiline = this.hasClass('multiline');
        var t = this.clone()
            .setStyle('display', 'none')
            .setStyle('position', 'absolute')
            .setStyle('overflow', 'visible')
            .setStyle('width', multiline ? this.getSize().x : 'auto')
            .setStyle('height', multiline ? 'auto' : this.getSize().y)
            .inject(this, 'after');

        function height() { return t.measure(t.getSize).y > this.getSize().y; };
        function width() { return t.measure(t.getSize().x > this.getSize().x; };

        var func = multiline ? height.bind(this) : width.bind(this);

        while (text.length > 0 && func()) {
            text = text.substr(0, text.lastIndexOf(' '));
            t.set('html', text + "...");
        }

        this.set('html', t.get('html'));
        t.dispose();
    }
}
});
1
iloveitaly

私はCSSの動作に少し驚いた。

var cssEllipsis = 
{   "width": "100%","display": "inline-block", 
"vertical-align": "middle", "white-space": "nowrap", 
"overflow": "hidden", "text-overflow": "Ellipsis" 
};

Ellipsisをバインドする必要があるコントロールに幅を指定しない限り、私の原因を支持しませんでした。追加する必要があるプロパティは幅ですか?ご意見をお聞かせください。

1
Premanshu

CSSのみを使用して省略記号を実行する

<html>
<head>
<style type="text/css">
#ellipsisdiv {
    width:200px;
    white-space: nowrap;  
    overflow: hidden;  
    text-overflow: Ellipsis;  
}  
</style>
</head>
<body>
<div id="ellipsisdiv">
This content is more than 200px and see how the the Ellipsis comes at the end when the content width exceeds the div width.
</div>
</body>
</html>

*このコードは現在のほとんどのブラウザで動作します。 OperaおよびIE(おそらくそうではないでしょう)で問題が発生した場合は、これらをスタイルに追加してください。

-o-text-overflow: Ellipsis;  
-ms-text-overflow: Ellipsis;

*この機能はCSS3の一部です。その完全な構文は次のとおりです。

text-overflow: clip|Ellipsis|string;
1
Robin Rizvi

Ellipsisが組み込まれた素敵なウィジェット/プラグインライブラリを次に示します。 http://www.codeitbetter.co.uk/widgets/Ellipsis/ All youライブラリを参照し、次を呼び出す必要があります。

<script type="text/javascript"> 
   $(document).ready(function () { 
      $(".Ellipsis_10").Ellipsis({ 
         numberOfCharacters: 10, 
         showLessText: "less", 
         showMoreText: "more" 
      }); 
   }); 
</script> 
<div class="Ellipsis_10"> 
   Some text here that's longer than 10 characters. 
</div>
1
Tim

希望どおりに動作するスクリプトを見つけることができなかったので、jQuery用に独自のスクリプトを作成しました。

https://github.com/rmorse/AutoEllipsis

1
acSlater

これは、cssのみで簡単に実行できます。たとえば、sassモード

.truncatedText {
   font-size: 0.875em;
   line-height: 1.2em;
   height: 2.4em; // 2 lines * line-height
   &:after {
      content: " ...";
   }
}

そして、あなたは省略記号を持っています;)

1
Apopii Dumitru
<html>
<head>
    <!-- By Warren E. Downs, copyright 2016.  Based loosely on a single/multiline JQuery using example by Alex,
    but optimized to avoid JQuery, to use binary search, to use CSS text-overflow: Ellipsis for end,
    and adding Marquee option as well.
    Credit: Marquee: http://jsfiddle.net/jonathansampson/xxuxd/
            JQuery version: http://stackoverflow.com/questions/536814/insert-Ellipsis-into-html-tag-if-content-too-wide
            (by Alex, http://stackoverflow.com/users/71953/alex)
            (Improved with Binary Search as suggested by StanleyH, http://stackoverflow.com/users/475848/stanleyh)
    -->
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <style>

        .single {
            overflow:hidden;
            white-space: nowrap;
            width: 10em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

        .multiline {
            overflow: hidden;
            white-space: wrap;
            width: 10em;
            height: 4.5em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

        .Marquee {
            overflow: hidden;
            width: 40em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

</style>
    <script>
        var _marqueeNumber=0;
        // mode=start,end,middle
        function clipText(text, len, mode) {
            if(!mode) { mode="end"; }
            else { mode=mode.toLowerCase(); }
            if(mode == "start") { return "&hellip;"+clipText(text,len,"_start"); }
            if(mode == "_start") { return text.substr(text.length - len); }
            if(mode == "middle") { 
                return clipText(text, len/2, "end") + clipText(text, len/2, "_start");
            }
            return text.substr(0, len) + "&hellip;";
        }

        function generateKeyframes(clsName, start, end) {
            var sec=5;
            var totalLen=parseFloat(start)-parseFloat(end);
            if(start.indexOf('em') > -1)      { sec=Math.round(totalLen/3); }
            else if(start.indexOf('px') > -1) { sec=Math.round(totalLen/42); }

            var style = document.createElement('style');
            style.type = 'text/css';
            style.innerHTML = 'body {}';
            document.getElementsByTagName('head')[0].appendChild(style);
            this.stylesheet = document.styleSheets[document.styleSheets.length-1];
            try {
                this.stylesheet.insertRule('.'+clsName+' {\n'+
                    '    animation: '+clsName+' '+sec+'s linear infinite;\n'+
                    '}\n', this.stylesheet.rules.length);
                this.stylesheet.insertRule('.'+clsName+':hover {\n'+
                    '    animation-play-state: paused\n'+
                    '}\n', this.stylesheet.rules.length);
                this.stylesheet.insertRule('@keyframes '+clsName+' {\n'+
                    '    0%   { text-indent: '+start+' }\n'+
                    '    100% { text-indent: '+end+' }\n'+
                    '}', this.stylesheet.rules.length);
            } catch (e) {
                console.log(e.message);
            }
        }

        function addClone(el, multiline, estyle) {
            if(!estyle) { 
                try { estyle=window.getComputedStyle(el); }
                catch(e) { return null; }
            }
            var t = el.cloneNode(true);
            var s=t.style;
            //s.display='none';
            s.visibility='hidden'; // WARNING: Infinite loop if this is not hidden (e.g. while testing)
            s.display='inline-block';
            s.background='black';
            s.color='white';
            s.position='absolute';
            s.left=0;
            s.top=0;
            s.overflow='visible';
            s.width=(multiline ? parseFloat(estyle.width) : 'auto');
            s.height=(multiline ? 'auto' : parseFloat(estyle.height));

            el.parentNode.insertBefore(t, el.nextSibling);

            return t;
        }
        function getTextWidth(el, multiline) {
            var t=addClone(el, multiline);
            if(!t) { return null; }
            var ts=window.getComputedStyle(t);
            var w=ts.width;
            if(multiline) {
                var es=window.getComputedStyle(el);
                var lines=Math.round(parseInt(ts.height)/parseInt(es.height))*2+0.5;
                w=w+'';
                var unit=''; // Extract unit
                for(var xa=0; xa<w.length; xa++) {
                    var c=w[xa];
                    if(c <= '0' || c >= '9') { unit=w.substr(xa-1); }
                }
                w=parseFloat(w);
                w*=lines; // Multiply by lines
                w+=unit; // Append unit again
            }
            t.parentNode.removeChild(t);
            return w;
        }

        // cls=class of element to ellipsize
        // mode=start,end,middle,marq (scrolling Marquee instead of clip)
        function Ellipsis(cls, mode) {
            mode=mode.toLowerCase();
            var elems=document.getElementsByClassName(cls);
            for(xa in elems) {
                var el=elems[xa];
                var multiline = el.className ? el.className.indexOf('multiline') > -1 : true;
                if(mode == "marq") {       
                    var w=getTextWidth(el, multiline);
                    if(!w) { continue; }
                    var mCls="dsmarquee"+(_marqueeNumber++);
                    var es=window.getComputedStyle(el);
                    generateKeyframes(mCls,es.width, '-'+w);
                    el.className+=" "+mCls; 
                    continue; 
                }
                if(mode == "end" && !multiline) { el.style.textOverflow="Ellipsis"; continue; }
                var estyle=null;
                try { estyle=window.getComputedStyle(el); }
                catch(e) { continue; }
                if(estyle.overflow == "hidden") {
                    var text = el.innerHTML;
                    var t=addClone(el, multiline, estyle);

                    function height() {
                        var ts=window.getComputedStyle(t);
                        var es=window.getComputedStyle(el);
                        return parseFloat(ts.height) - parseFloat(es.height); 
                    }
                    function width() { 
                        var ts=window.getComputedStyle(t);
                        var es=window.getComputedStyle(el);
                        return parseFloat(ts.width) - parseFloat(es.width); 
                    }

                    var tooLong = multiline ? height : width;

                    var len=text.length;
                    var diff=1;
                    var olen=0;
                    var jump=len/2;
                    while (len > 0) {
                        var diff=tooLong();
                        if(diff > 0) { len-=jump; jump/=2; }
                        else if(diff < 0) { len+=jump; }
                        len=Math.round(len);
                        //alert('len='+len+';olen='+olen+';diff='+diff+';jump='+jump+';t='+JSON.stringify(t.innerHTML));
                        t.innerHTML=clipText(text, len, mode);
                        if(olen == len) { break; }
                        olen=len;
                    }
                    el.innerHTML=t.innerHTML;
                    t.parentNode.removeChild(t);
                }           
                //break;
                t.style.visibility='hidden';
            }
        }

        function testHarness() {
            Ellipsis('Ellipsis1', 'start'); 
            Ellipsis('Ellipsis2', 'end'); 
            Ellipsis('Ellipsis3', 'middle'); 
            Ellipsis('Marquee', 'marq')
        }
    </script>
    </head>
    <body onload="testHarness()">
    <div class="single Ellipsis1" style="float:left">some long text that should be clipped left</div>
    <div class="single Ellipsis2" style="float:right">right clip long text that should be clipped</div>
    <div class="single Ellipsis3" style="float:center">some long text that should be clipped in the middle</div>

    <br />

    <p class="single Marquee">Windows 8 and Windows RT are focused on your life—your friends and family, your apps, and your stuff. With new things like the <a href="http://windows.Microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.Microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.Microsoft.com/en-US/windows-8/Microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
    &nbsp;

    <br />

    <div class="multiline Ellipsis1" style="float:left">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped left(*)</div>

    <div class="multiline Ellipsis2" style="float:right">right clip multiline long text, such as Test test test test test test, and some more long text that should be multiline clipped right.</div>

    <div class="multiline Ellipsis3" style="float:center">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped in the middle(*)</div>

    <br />

    <p class="multiline Marquee">Multiline Marquee: Windows 8 and Windows RT are focused on your life—your friends and family, your apps, and your stuff. With new things like the <a href="http://windows.Microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.Microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.Microsoft.com/en-US/windows-8/Microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
    &nbsp;

    </body>
</html>
0
Warren Downs