开发者

jQuery/JavaScript: Why does this freeze?

I'm trying to implement a requirement that requires I set a maximum line length for the contents of a div element. But when I open the page in Firefox, 开发者_运维问答I get an error about a "long-running script" and am asked to Continue, Debug, or Stop Script. I don't understand why this is happening. This is my code:

    <html>
    <head>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
        <script type="text/javascript">

            $.fn.lineCount = function () {
                var lineHeight = this.css("line-height"); // returns "Xpx"
                return document.getElementById(this.attr("id")).offsetHeight / parseInt(lineHeight.substr(0, lineHeight.length - 2));
            };

            $.fn.truncateLineCount = function (countAfterTruncation) {
                while (this.lineCount() > countAfterTruncation) {
                    var text = this.html();
                    this.html(text.substr(0, text.length - 1) + "&hellip;");
                }
            };

            $(function () {
                $("#title").truncateLineCount(3);
            });
        </script>
    </head>

<body>
 <div id="title">
  My MVC Application<br />
  steaks<br />
  are<br />
  awesome
 </div>
</body>
</html>

What gives?


I don't think your truncate function works.

At each iteration of your while loop, you are removing 1 character but adding 8 more ("&hellip;").

You may want to add the ellipsis after the loop.


this.html(text.substr(0, text.length - 1) + "&hellip;");

this line increases the charater count. it removes last character, but it adds "&hellip;" to end of the line. so the text will never be truncated.

if your text is My MVC Application, after some while loop, it becomes: My MVC Applicatio................

your loop should be:

while (this.lineCount() > countAfterTruncation) {
    var text = this.html();
    this.html(text.substr(0, text.length - 1));
}
this.html(this.html()+"&hellip;");


The default value for the line-height CSS property is normal. This line:

var lineHeight = this.css("line-height"); // returns "Xpx"

Is actually returning "normal", which your code then attempts to parse into an integer, which yields NaN.

http://www.w3.org/TR/CSS2/visudet.html#propdef-line-height

Aside from that, as others have mentioned, your loop removes 1 character and adds another 8 so it will never get any shorter. You should append &hellip; after the loop ends and your line is short enough:

            while (this.lineCount() > countAfterTruncation) {
                this.html(this.html().slice(0, -1));
            }
            this.html(this.html()+"&hellip;");

As an aside, I feel it necessary to add a few pointers for your code:

  • As I mentioned in the comments, you don't need to snip off the px when parsing a string like "12px" with parseInt().
  • Don't use the var keyword inside a loop, this reinitializes the variable on each iteration which, aside from being bad practice, will throw an error in ECMAScript 5th's strict mode.
  • You can use the slice() method with a negative offset for the second parameter instead of using substring() and passing string length - 1.
  • Instead of document.getElementById(this.attr("id")), you can just use this.get(0). this is already an element wrapped by jQuery, you can access the underlying element using the get() method.
  • If you can help it, don't manipulate html()/innerHTML inside loops. The performance is very poor since it invokes the HTML parser on every iteration of the loop.


within your $.fn's your using this instead of the jQuery $(this).. This could be causing an infinite loop in your while () statement.


I think you're using line-height the wrong way. That property only gives you the height of each line in a paragraph, it's used to measure space between two lines, not to count how many lines you have in your paragraph.

You remove text from the content in your truncateLineCount() but lineCount always has the same value, thus the while cycle is never ending...

P.S. Be careful: truncateLineCount also removes html (char by char), not only text.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜