JavaScript 代码适用于 chrome,不适用于 IE 和 firefox

标签 javascript

出于教育原因,我用纯 JS 创建了这个脚本。它向表格添加排序(单击标题时)。我认为它非常有用并尝试在我的项目中使用它。它在 Google Chrome 上运行良好(我在创建脚本时使用了这个浏览器),但在 IE 和 Firefox 上运行不佳。你能帮我吗?

alert("Remember to add LoadSetup function to window.onload event and to remove this alert.\nAlso remember that table you want to sort must have class 'sortable' and an unique id.\nThe table must be build properly using <thead> and <tbody> tags.")


function addLoadEvent(func) {
// Dobra funkcja która radzi sobie z dodawaniem nowych funkcji do zdażenia window.onload
    var oldonload = window.onload;
    if (typeof window.onload != 'function') window.onload = func;
    else {
        window.onload = function() {
            if (oldonload) oldonload();
            func();
        }
    }
}

window.onload = LoadSetup;

function LoadSetup()
{
    //find sortable tables and set sorting state to 0 (not sorted)  
    tables = document.getElementsByTagName("table");
    tablesStates = new Array(tables.length);

    for(var i=0;i<tables.length;i++){
        tableName = tables[i].getAttribute("id");
        if(hasClass(tables[i], "sortable") && tableName != null){
            tablesStates[tableName] = new Array();

            thead = tables[i].getElementsByTagName("thead")[0];
            header = thead.getElementsByTagName("tr")[0].getElementsByTagName("th");

            for(var j=0; j<header.length; j++){
                if(!hasClass(header[j], 'notsortable')){
                    tablesStates[tableName][header[j].innerHTML] = 0;
                    header[j].removeAttribute("onclick");
                    header[j].setAttribute("onclick", "sortTable('"+tableName+"', '"+header[j].innerHTML+"')");
                }
            }
        }
    }
}

function hasClass(ele, cls)
{
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

String.prototype.capitalize = function() {
// fajna funkcja
    return this.charAt(0).toUpperCase() + this.slice(1);
}
String.prototype.capitalizeAll = function() {
// fajna funkcja
    result = '';
    for(var i=0; i< this.length;i++)
        result += this.charAt(i).toUpperCase();
    return result;
}

function prepareStringForCmp(s){
    en = ['a','c','e','l','n','o','s','z','z','A','C','E','L','N','O','S','Z','Z'];
    pl = ['ą','ć','ę','ł','ń','ó','ś','ź','ż','Ą','Ć','Ę','Ł','Ń','Ó','Ś','Ź','Ż'];

    for(var i=0;i<pl.length;i++){
        regex = new RegExp(pl[i],"g");
        s = s.replace(regex,en[i]);
    }
    return s.capitalizeAll();
}

function cmpStr(a, b){
    //a=prepareStringForCmp(a);
    //b=prepareStringForCmp(b);
    if(a == b)return 0;
    else if(a > b) return 1;
    else return -1;
}
function cmpStrRev(a, b){return cmpStr(b, a);}

function cmpNum(a, b){ return a - b;}
function cmpNumRev(a, b){return cmpNum(b, a);}

function cmp(a,b,type,asc)
{
// returns -1 if a < b ---- in ascending mode ( asc=true)
// returns 1 is a > b ---- in ascending mode ( asc=true)
// returns 0 if a == b

    if(type == "number"){
        if(asc == true) return cmpNum(a,b);
        else return cmpNumRev(a,b);
    }
    else if(type == "date"){
        if(asc == true) return 0;
        else return 0;
    }
    else{
        if(asc == true) return cmpStr(a,b);
        else return cmpStrRev(a,b);

    }
}

/////////////////////////////////////////////////////////////
// Bubble Sort

function bubbleSortTable(tab, col, type, asc) {
    for(var i=0; i < tab.length; i++){
        for(var j=0; j< tab.length-1; j++){
            if(cmp(tab[j].getElementsByTagName("td")[col].innerText, tab[j+1].getElementsByTagName("td")[col].innerText, type, asc) > 0)
            {
                buf = tab[j].innerHTML;
                tab[j].innerHTML = tab[j+1].innerHTML;
                tab[j+1].innerHTML = buf;
            }
        }
    }
}

/////////////////////////////////////////////////////////////
// Quick Sort

function partitionTable(l, r, A, col, type, asc)
{
    x = A[l].getElementsByTagName("td")[col].innerText;
    i = l-1;
    j = r+1;
    while(true){
        while(true){
            j = j-1;
            if(cmp(A[j].getElementsByTagName("td")[col].innerText, x, type, asc) <= 0) break;
        }
        while(true){
            i = i+1;
            if(cmp(A[i].getElementsByTagName("td")[col].innerText, x, type, asc) >= 0) break;
        }

        if(i<j){
            buf = A[i].innerHTML;
            A[i].innerHTML = A[j].innerHTML;
            A[j].innerHTML = buf;
        }
        else return j;
    }

}

function qsortTable(l, r, A, col, type, asc)
{
//qsort(tablica, 0, tablica.lenght -1);
    if(l<r){
        q = partitionTable(l, r, A, col, type, asc);
        qsortTable(l, q, A, col, type, asc);
        qsortTable(q+1, r, A, col, type, asc);
    }
}

/////////////////////////////////////////////////////////////

function sortTable(id, colName){
// sorts table
// returns true if sorting done; otherwise false
// works for strings and numbers


    if(tablesStates[id][colName] >= 0) asc = true;
    else asc = false;

    tab = document.getElementById(id);
    thead = tab.getElementsByTagName("thead")[0];
    header = thead.getElementsByTagName("tr")[0].getElementsByTagName("th");
    tbody = tab.getElementsByTagName("tbody")[0];
    rows = tbody.getElementsByTagName("tr");

    col = -1;
    for(var i=0; i < header.length; i++){
        if(header[i].innerHTML == colName){
            col = i;
            colType = header[i].getAttribute("class");      
            break;
        }
    }
    if(col == -1) return false;

    // demanded header found

    bubbleSortTable(rows, col, colType, asc);
    //qsortTable(0, rows.length-1,rows, col, colType, asc);
    if(tablesStates[id][colName] >= 0) tablesStates[id][colName] = -1;
    else tablesStates[id][colName] = 1;
}

还有一个简单的 html:

<!DOCTYPE html PUBLIC 
"-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
xml:lang="pl" lang="pl">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="sortTable.js"></script>
    <link rel="stylesheet" type="text/css" href="x.css" />
</head>
<body>
<div id="content_box">

<table class="sortable"  id="tabela1">
<thead>
    <tr><th>name</th><th class="number">age</th><th>city</th></tr>
</thead>
<tbody>
    <tr> <td>Jan</td> <td>21</td> <td>Gdańsk</td> </tr>
    <tr> <td>Andrzej</td> <td>17</td> <td>Warszawa</td> </tr>
    <tr> <td>Paweł</td> <td>112</td> <td>toruń</td> </tr>
    <tr> <td>Mateusz</td> <td>43</td> <td>Łomża</td> </tr>
        <tr> <td>ADAM</td> <td>21</td> <td>Gdańsk</td> </tr>
    <tr> <td>ŻANETA</td> <td>17</td> <td>Warszawa</td> </tr>
    <tr> <td>Paweł</td> <td>112</td> <td>toruń</td> </tr>
    <tr> <td>LEON</td> <td>43</td> <td>Łomża</td> </tr>
        <tr> <td>Jan</td> <td>21</td> <td>Gdańsk</td> </tr>
    <tr> <td>Andrzej</td> <td>17</td> <td>Warszawa</td> </tr>
    <tr> <td>FRYDERYK</td> <td>112</td> <td>toruń</td> </tr>
    <tr> <td>Mateusz</td> <td>43</td> <td>Łomża</td> </tr>
        <tr> <td>Jan</td> <td>21</td> <td>Gdańsk</td> </tr>
    <tr> <td>BALBINA</td> <td>17</td> <td>Warszawa</td> </tr>
    <tr> <td>ADAM</td> <td>112</td> <td>toruń</td> </tr>
    <tr> <td>TERESA</td> <td>43</td> <td>Łomża</td> </tr>
</tbody>
</table>
</div>
</body>
</html>

更详细的描述:

LoadSetup - 有效(并添加排序功能) 当点击 header 时,它应该进行排序,在 Chrome 上也是如此。 比它像这样: sortTable >> bubbleSortTable >> cmp 在 cmp(a,b,type,asc) 中,a 和 b 在 Firefox 和 IE 中是“未定义”,并且脚本某处中断并且没有任何内容被排序。

最佳答案

我不会仔细检查你的所有代码,特别是因为你的描述相当模糊:“不起作用”是显而易见的 - 你不会在这里问是否一切正常,所以更具体一点并尝试缩小范围将问题解决(从而发布更少的代码)可能是一个好主意。但从我看了三秒后,我发现您正在使用 setAttribute 设置事件处理程序。这不是一个好主意(例如,请参阅 this post )。这在某些版本的 IE 中不起作用(同样,版本是您没有指定的内容)。

要添加一件事:甚至不建议这样做 elem.onclick = ... 。这是旧的 HTML 4.0 方法。建议使用 DOM 事件模型,即(addEventListener 等)。但随之而来的是无穷无尽的跨浏览器问题,这就是为什么有js库的原因。因此,我建议将您的代码移植到 jQuery 或其他类似的库,以使代码真正可移植。

这是一个好主意,否则您最终会重新发明轮子,而且可能还不如多年经验丰富的开发人员所做的那样。此外,您可能会添加此代码并且它会增长。正确使用 Node.js 库将有助于代码的可扩展性。

不,这不是您问题的答案。如果您正在寻找问题的快速解决方案,那么这不是您想要的。但我强烈认为,这个建议虽然在短期内很难(更难)实现,但如果您希望该代码真正可用和可维护,那么它是您最好的选择。

关于JavaScript 代码适用于 chrome,不适用于 IE 和 firefox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7589447/

相关文章:

javascript - 将 LDAP 组成员身份转换为 Keycloak 中的 SAML 属性

javascript - 如何在 sweet.js 中创建参数化中缀宏

javascript - D3 v4 过渡或更新

javascript - Angular 指令 ng-model 适用于数组,但不适用于字符串

javascript - 确定元素的高度

javascript - jQuery 包装每个数组项

javascript - 如何获取事件信息并将其显示在 FullCalendar.js 的工具提示中?

javascript - 如何在 Symfony 3 中以 Json 形式从存储库返回对象

javascript - border-radius 在两个值之间使用斜杠 ("/")

javascript - 如何使用 jQuery detach() 方法在 DOM 中切换元素?