【问题标题】:Javascript code to shorten long text needs optimization缩短长文本的 Javascript 代码需要优化
【发布时间】:2011-07-21 18:29:22
【问题描述】:

注意:最初将此列为内存泄漏。在深入研究之后,我发现这不是内存问题。这只是一个非常缓慢的脚本。任何加快这一进程的建议将不胜感激。

另一个注意事项: 进一步研究后,我发现 FF 不支持任何类型的 CSS 来格式化溢出的文本。有一个 hack 和一个 workaround 用于该黑客......但这不是一个合适的解决方案。

我已经投票支持并加入了 mozilla 上 particular bug 的电子邮件列表。它已经快六年了,所以我决定用户现在只需要处理它。至少这不是我们产品的常见场景。

原帖:

脚本截断元素的值并在其 scrollWidth 大于其 offsetWidth 时附加“...”。 (例如,“LastName,VeryLongFirstName”的值将更改为“LastName,Ver...”,具体取决于列的宽度)

var eTable = document.getElementById(this._eDiv.id + "_tbl");

//...lots of code here...

//function called that gets all cells in a table, loops through them and clips the text
addEventListenerEx(window, "load", function() {     
        var aCells = eTable.getElementsByTagName("DIV");
        window.alert(aCells.length);   
            //When aCells is length of 100, we're ok...but when it's big (like 3,000) I have problems         
        for (var i = 0; i < aCells.length; i++){
            Grid.clipText(aCells[i]);
        }
}, false);

//...lots of code here...

//This is the function doing the actual clipping
Grid.clipText = function (oDiv) {   

    //for tooltip       
    var oCurDiv;
    var oTagA;
    var sToolTip;       
    if (oDiv.firstChild) {
            if (oDiv.firstChild.firstChild){            
                oCurDiv = oDiv.firstChild;
                while (oCurDiv) {
                    if (is.ie) {
                        oTagA = oCurDiv;                        
                    } else {
                        // there are some different between IE & FireFox.
                        oTagA = oCurDiv.firstChild.parentNode;                      
                    }
                    if (oTagA.tagName == "A") {
                        sToolTip = oTagA.innerHTML;     
                        if (sToolTip.indexOf('<b>') > 0) {
                            sToolTip = sToolTip.replace('<b>',"");
                            sToolTip = sToolTip.replace('</b>',"");
                        }
                        if (sToolTip.indexOf('<B>') > 0) {
                            sToolTip = sToolTip.replace('<B>',"");
                            sToolTip = sToolTip.replace('</B>',"");
                        }                       
                        oTagA.parentNode.title = convertHTMLToText(sToolTip);
                    }
                    oCurDiv = oCurDiv.nextSibling;                                      
                }
            } else {
                oDiv.title = convertHTMLToText(oDiv.innerHTML);
            }
        }

        //NOTE:  Additional steps to take for non-IE browsers
        if (!is.ie) {
                    var oText = oDiv;           
                    while (oText.nodeType != 3) {
                        oText = oText.firstChild;
                    }

                    var sDisplayText = oText.nodeValue;
                    if (sDisplayText.length < 3) return; 

                    var lastThree;
                    sDisplayText = sDisplayText.slice(0, parseInt(oDiv.offsetWidth / 5));
                    oText.nodeValue = sDisplayText + "...";

                    //NOTE:  Bad things happen here because of this loop
                    while (oDiv.scrollWidth > oDiv.offsetWidth && sDisplayText != "") {
                        lastThree = sDisplayText.slice(-3);
                        sDisplayText = sDisplayText.slice(0, sDisplayText.length - 3);
                        oText.nodeValue = sDisplayText + "...";
                    }
                    oText.nodeValue = sDisplayText + lastThree.slice(0, 1) + "...";
                    while (oDiv.scrollWidth > oDiv.offsetWidth && sDisplayText != "") {
                        oText.nodeValue = sDisplayText + "...";
                    }
                }

代码有效。但是,问题是在页面上加载表格后会一遍又一遍地调用它。当表格很大(>1,500 个单元格)时,问题就开始了。

所以,我真的在寻找一种方法来使这个示例(尤其是 WHILE 循环)更高效。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    其中没有任何东西会自行泄漏。您可能在闭包中泄漏了oText,您可以显示周围的代码吗?

    顺便说一句,这是一种更有效的方法:

    http://jsfiddle.net/cwolves/hZqyj/

    如果你真的想保持原样,你可以通过获取字符串的长度并将其乘以它需要的比例宽度来估计截止点......

    例如如果字符串是 100 个字符并且它的长度是应有的 2 倍,则将其剪切为 50 个字符并重新检查。或者你可以实现一个二进制“搜索”算法来获得正确的长度。

    【讨论】:

    • 哦...我很想在 jQuery 中做到这一点! :) 唉,我不能。加载并最终调用此代码的页面可能有也可能没有对 jQuery 的引用。
    • 你可以在没有 jQuery 的情况下做到这一点。 jQuery 只是在做同样的检查。 CSS 中的“魔法”只是在子项比父项长时显示省略号。
    • @cwolves...谢谢。你说的对。我能。抱歉……当我看到那个“$”时,我很快就放弃了 jQuery。我应该更加注意的。好的,为了提供更好的图片,我添加了更多代码。希望能更清楚为什么我会遇到这个问题。
    • 其中也不应该泄漏...您确定有泄漏并且不仅仅是代码很慢吗?您正在替换 who-knows-how-many 单元格中的内容 who-knows-how-many 次...
    • 代码肯定很慢。但是,记忆中似乎也有一些东西。如果我在页面加载时在任务管理器中观看 FF,则在脚本超时之前内存将上升到半个演出。但是,如果我在 aCells 循环中处理每 500 条记录后向弹出窗口添加一个警报,则内存会上升到 120mb,然后在每次警报后下降到 80mb。
    【解决方案2】:

    我的问题的解决方法和最佳答案来自基本算术:cross multiplication

    我在更受欢迎的stackoverflow thread 中发布了我的答案,更详细地讨论了该主题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-30
      相关资源
      最近更新 更多