0

我正在编写一些将表格包装在 div 中的 JavaScript。我想为 div 元素赋予与源表相同的边框样式。

我应该能够以编程方式查询 DOM 中的表格并获取它的边框设置,但是当我在运行时检查表格样式对象的属性时,它们是空字符串。

我将如何复制现有元素的样式设置?

提前致谢。

编辑:源代码


HTML 测试代码

        <table id="tbWorking" class="tbTest">
            <tr class="trTest">
                <th class="tdTest">Col1</th>
                <th class="tdTest">Col2</th>
            </tr>  
            <tr class="trTest">
                <td class="tdTest">a</td>
                <td class="tdTest">b</td>
            </tr>
            <tr class="trTest">
                <td class="tdTest">c</td>
                <td class="tdTest">d</td>
            </tr>
            <tr class="trTest">
                <td class="tdTest">e</td>
            </tr>        
        </table>

        <script type="text/javascript" src="TempTestingTables.js"></script>

CSS 类

    .tbTest
    {
        empty-cells: show;    
        border-collapse:separate; /* Table and Cell borders are unique */

        border-width:1px;
        border-style:solid;
        border-color:Navy;

        background-color:#DDDDDD; /* Colour of gaps between cells */
        color:Black; /* Text colour */
    }

    .trTest
    {
        background-color:#DAD7FA;
    }

    .tdTest
    {
        padding:150px;

        border-color:#7D72FC;
        border-width:1px;
        border-style:solid;    
    }

页面本地的 JavaScript

    // Set a custom flag to indicate that the document has not yet loaded
    onLoad.loaded = false;
    // Register a function on the window object that sets the flag true when the document is loaded
    onLoad(function () { onLoad.loaded = true; });
    // This should then allow the FC function addEvent() to browser-agnostically 
    // register handlers for controls on startup

    // Once the page has loaded, set the background colour of the order ticket
    // based on the Buy/Sell selection
    onLoad(prepareTables());

    function prepareTables() {
        // Function to prepare the tables are scrollable
        prepTable("tbWorking",2);
    }

    function prepTable(sTable, rowsToShow) {

        // Pass in a table, and the number of data rows, not including the header, to display

        var tableSource = document.getElementById(sTable);
        if (tableSource == null) { return; }

        var rowHeight = GetTableRowHeight(sTable);

        var countRows = tableSource.rows.length;
        if (countRows == null || countRows == 0)
            return;

        // There is at least one row

        // Copy the table
        var tableCopy = tableSource.cloneNode(true);
        tableCopy.id = sTable + "_header";

        // Delete all except the first row
        var i = 1;
        for(;i < countRows;++i)
        { tableCopy.deleteRow(1); }

        // Insert the copy above the source table
        (tableSource.parentNode).insertBefore(tableCopy, tableSource);

        // Get the height of the header for later when we need to account for it in the wrapper tableDiv element
        var heightHeader = tableCopy.offsetHeight;


        // Move top row to the end of the table
        var rowHeaderCopy = tableCopy.rows[0].cloneNode(true); // copy the row
        rowHeaderCopy.style.visibility = "hidden"; // stop the row being displayed, but still let it contribute to layout
        tableSource.appendChild(rowHeaderCopy);

        // Hide the first row of the source table
        //tableSource.rows[0].style.display = "none"; 
        // Re-think: Delete the first row of the source table to stop it jiggering the sorting
        tableSource.deleteRow(0);


        // Wrap the source table in a div tag that is fixed size, to give us vertical scrolling on the body only   

        var bodywrapper = document.createElement("div");
        bodywrapper.id = "divBody_" + sTable;
        bodywrapper.style.overflow = "auto";

        var heightRequired = rowsToShow * rowHeight;
        bodywrapper.style.height = heightRequired + "px";

        var widthTableSource = tableSource.offsetWidth;
        var widthRequired = widthTableSource + getScrollBarWidth();
        bodywrapper.style.width = widthRequired + "px";

        // Get the border style of the table and make the div have the same style,
        // And then turn off the border style of the body (maybe, still designing).
        //var border = tableSource.style.getAttribute("border-width"); // Attempt to read style FAILED
        //var style = document.defaultView.getComputedStyle(tableSource, ""); // Attempt to read Computed Style FAILED
        //bodywrapper.style.border = "black 1px solid"; // Hard coded bodge

        // The node to wrap is the tableSource
        tableSource.parentNode.insertBefore(bodywrapper, tableSource);
        tableSource.parentNode.removeChild(tableSource);
        bodywrapper.appendChild(tableSource);

        // Wrap the whole lot in another DIV element to give us horizontal scrolling for header and body
        var tablewrapper = document.createElement("div");
        tablewrapper.id = "divTable_" + sTable;
        tablewrapper.style.overflow = "auto";

        // Height of the outer wrapping DIV is the header height, plus body height, plus one scrollbar
        tablewrapper.style.height = 1 + getScrollBarHeight() + heightHeader + heightRequired + "px"; 

        // Width of the out DIV is default, 100%, so that scrollbar only appears 
        // if table is wider than available screen real estate.

        tableCopy.parentNode.insertBefore(tablewrapper, tableCopy); // Put the tablewrapper DIV in front of the header
        tableCopy.parentNode.removeChild(tableCopy); // Cut the header out
        bodywrapper.parentNode.removeChild(bodywrapper); // Cut the table body out
        tablewrapper.appendChild(tableCopy); // Add the header to the contents of the tablewrapper DIV
        tablewrapper.appendChild(bodywrapper); // Add the table body to the contents of the tablewrapper DIV
    }

    function GetTableRowHeight(sTable) {
        var table = document.getElementById(sTable);
        if (table == null) { return 32; }
        var countRows = table.rows.length;
        var heightTable = table.offsetHeight+1;
        return (heightTable / countRows);
    }

常见的 JavaScript

    ///////////////////////////////////////////////////////////////////////////////
    // Invoke functions once the document is loaded
    // 
    // Usage: 
    // Start by setting a flag to indicate that the document is not yet loaded...
    //     onLoad.loaded = false;
    // Then register a function to set the flag when the document loads...
    //     onLoad(function(){ onLoad.loaded=true; });
    //
    function onLoad(f) {
        if (onLoad.loaded)
            window.setTimeout(f, 0);
        else if (window.addEventListener)
            window.addEventListener("load", f, false);
        else if (window.attachEvent)
            window.attachEvent("onload", f);
    }
    //
    ///////////////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////////////
    //
    // Graphics Functions

    // Sometimes you have to account for scrollbar widths etc.  
    function getScrollBarWidth() {
        var inner = document.createElement('p');
        inner.style.width = "100%";
        inner.style.height = "200px";

        var outer = document.createElement('div');
        outer.style.position = "absolute";
        outer.style.top = "0px";
        outer.style.left = "0px";
        outer.style.visibility = "hidden";
        outer.style.width = "200px";
        outer.style.height = "150px";
        outer.style.overflow = "hidden";
        outer.appendChild(inner);

        document.body.appendChild(outer);
        var w1 = inner.offsetWidth;
        outer.style.overflow = 'scroll';
        var w2 = inner.offsetWidth;
        if (w1 == w2) w2 = outer.clientWidth;

        document.body.removeChild(outer);

        return (w1 - w2);
    };


    // Sometimes you have to account for scrollbar widths etc.  
    function getScrollBarHeight() {
        var inner = document.createElement('p');
        inner.style.height = "100%";
        inner.style.width = "200px";

        var outer = document.createElement('div');
        outer.style.position = "absolute";
        outer.style.top = "0px";
        outer.style.left = "0px";
        outer.style.visibility = "hidden";
        outer.style.width = "150px";
        outer.style.height = "200px";
        outer.style.overflow = "hidden";
        outer.appendChild(inner);

        document.body.appendChild(outer);
        var h1 = inner.offsetHeight;
        outer.style.overflow = 'scroll';
        var h2 = inner.offsetHeight;
        if (h1 == h2) h2 = outer.clientHeight;

        document.body.removeChild(outer);

        return (h1 - h2);
    };


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

解决方案:

下面的函数应该不可知地查询元素的样式对象并返回所需的内容。当然,JQuery 会更可靠,毫无疑问。我决定不尝试借用表格的边框,因为它使整个操作非常复杂且容易出错,因为这实际上只是一个很好的优势。但是,下面的功能很有用,其他人也可能会觉得它有帮助。请记住,如果样式是这样设置的,IE 会返回 em 和百分比,它不会为您转换为 px。毕竟,你为什么要这样?(哈哈抱歉)。

    // Custom version, reverses the if-clause logic to test for IE9 first, 
    // as IE9 does not return null for getComputedStyle.
    // CREDIT: Robert Nyman (search using getStyle,oElm,strCssRule)
    function getStyle(oElm, strCssRule) {
        var strValue = "";
        if (oElm.currentStyle) {
            strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) {
                return p1.toUpperCase();
            });
            strValue = oElm.currentStyle[strCssRule];
        }
        else if (document.defaultView && document.defaultView.getComputedStyle) {
            var style = document.defaultView.getComputedStyle(oElm, "");
            strValue = style.getPropertyValue(strCssRule);
        }

        return strValue;
    }
4

2 回答 2

0

如果 dom 尝试“重组”/“修复”您的代码,请使用 firebug 或类似的东西来检查表:

<table>
    <tbody>
    </tbody>
</table>

并且 tbody 包含边框属性。

于 2012-10-25T16:02:43.303 回答
0

你为什么要这样做,而不是给 table 和 div 同一个类,然后将边框样式放在那个类中,而不是在 table 上内联?

另外,你什么时候检查样式对象的属性?如何?需要看你的代码。如果您试图在 DOM 准备好之前获取这些样式(例如在某些情况下触发 DOM.onload 之前),那么对象将不会准备好并且您将不会获得任何值。

已编辑

好的,鉴于上面的代码,我可以对你的 CSS 进行轻微的重构感兴趣吗?:)

让我们来看看:

.tbTest
{
    empty-cells: show;    
    border-collapse:separate; /* Table and Cell borders are unique */

    border-width:1px;
    border-style:solid;
    border-color:Navy;

    background-color:#DDDDDD; /* Colour of gaps between cells */
    color:Black; /* Text colour */
}

并将其分开,以便您的表格特定样式与边框样式分开:

.tbTest
{
    empty-cells: show;    
    border-collapse:separate; /* Table and Cell borders are unique */
    background-color:#DDDDDD; /* Colour of gaps between cells */
    color:Black; /* Text colour */
}

.borderSpec 
{
    border:1px solid Navy;
}

将 .borderSpec 添加到您的表格中:

    <table id="tbWorking" class="tbTest borderSpec">
        <tr class="trTest">
            <th class="tdTest">Col1</th>
            <th class="tdTest">Col2</th>
        </tr>  

现在,在您的 Javascript 中,进行一些小修改:

function prepTable(sTable, rowsToShow) {
    var tableSource = document.getElementById(sTable);
    if (tableSource == null) { return; }

    // clear off the borderSpec from your tableSource
    tableSource.setAttribute("class","tbTest");

    /* ... snip ... */

    // Wrap the whole lot in another DIV element to give 
    // us horizontal scrolling for header and body
    var tablewrapper = document.createElement("div");
    tablewrapper.id = "divTable_" + sTable;
    tablewrapper.style.overflow = "auto";

    // Now, add borderSpec to your wrapper-div
    tablewrapper.setAttribute("class","borderSpec");

这样做是从表中删除borderSpec,并将borderSpec 添加到您的包装器div,以便包装器获取边框,而表没有。

jsFiddle,这里:http: //jsfiddle.net/mori57/35e6B/

于 2012-10-25T16:00:25.887 回答