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

テーブルと div の両方に同じクラスを与えるのではなく、テーブルのインラインではなく、そのクラスにボーダー スタイルを配置するのはなぜですか?

また、いつスタイル オブジェクトのプロパティをチェックしますか? どのように?あなたのコードを見る必要があります。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 に答える
0

コードを「再編成」/「修復」しようとしている場合は、firebugまたはこのようなものを使用してテーブルを確認してください。

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

および tbody には、border プロパティが含まれています。

于 2012-10-25T16:02:43.303 に答える