0

经过数小时的压力,我才让这段代码正常工作。我是 Javascript 的新手,所以我不确定我是否以最有效的方式做到了这一点。我正在使用 IEX 提供的 API。此代码的目标是在有消息时输出消息。正如你所知道的,这并不完全有效,但我确实得到了标题。所以,如果我做错了什么,请告诉我。

<html>
<head>
    <style>
        /* Outter Table <Tbody> Settings*/
        .outtertable tbody {
            vertical-align: top;
        }

        /* Innertable Table data settings */
        .innertable tr > td {
            vertical-align: top;
        }

        /* Div Article Holder Settings */
        .divBorder {
            margin-bottom: 10px;
            border: solid; 
            border-color: #c4ef8b; 
            border-width: 4px 0px 0px 0px;
        }

        /* Article Image settings */
        .articleImg {
            height:50px; 
            width: 50px;
        }

        /* DivBorder Mouse Hover */
        .divBorder:hover {
            cursor: pointer;
            background-color: #f3ffe5;
        }
    </style>
</head>

<body>
    <table class="outterTable" id="newsContent"></table>
</body>

<script>
    var request = new XMLHttpRequest();
    request.open ('GET', 'https://api.iextrading.com/1.0/stock/spy/news')

    //on request load
    request.onload = function() {
        //VARIABLES
        var newsContainer = document.getElementById("newsContent");

        var JSONData = JSON.parse(request.responseText);
        var articleAmount = JSONData.length;
        var rowAmount = articleAmount / 3;
        var rowAmountRoundDown= Math.trunc(rowAmount); 
        var rowAmountRoundUp = (Math.trunc(rowAmount) + 1);
        var remainder = (rowAmount - Math.floor(rowAmount)).toFixed(2); //.00, .67, or .33;

        //=== TABLE CREATOR =============================================
        //Create an "<tbody>" element
        let tbodyHTML = document.createElement('tbody');

        //"Assembler" inside is "createTable()"
        tbodyHTML.innerHTML = createTable();

        //FUNCTION Create Table
        function createTable() {
            var tData = '';
            var index = 0; 

            //========= First Table Part Row Loop ===========================================================
            for (var i = 1; i <= rowAmountRoundDown; i++) {         
                //Row Start
                tData = tData + `
                    <tr>
                `;

                //Content: <td> <div> <table> <tr> <td>
                for (var c = 1 + index; c < 4 + index; c++) {
                    tData = tData + `
                        <td style="width: 33.33%; padding: 0px 25px">
                            <div class="divBorder">
                                <table class="innerTable">
                                    <tbody>
                                        <tr>
                                            <td>
                                                <img class="articleImg" src="images/seeking-alpha-badge.png" id="image${c}">

                                            </td>
                                            <td style="padding-left: 5px">
                                                <h3 id="headline${c}"></h3>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>        
                            </div>
                        </td>
                    `;
                }

                //Row End
                tData = tData + `
                    </tr>
                `;

                index = index + 3;
            }

            //========= Second table part =====================================================================
            //If remainder is .67 create 2 <td>
            if (remainder == 0.67) {
                //Row Start
                tData = tData + `
                <tr>
            `;

            //Content: <td> <div> <table> <tr> <td> 
            for (var c2 = (1 + index); c2 < (3 + index); c2++){
                tData = tData + `
                    <td style="width: 33.33%; padding: 0px 25px">
                        <div class="divBorder">
                            <table class="innerTable">
                                <tbody>
                                    <tr>
                                        <td>
                                            <img class="articleImg" src="images/seeking-alpha-badge.png" id="image${c2}">

                                        </td>
                                        <td style="padding-left: 5px">
                                            <h3 id="headline${c2}"></h3>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>        
                        </div>
                    </td>
                `;
            }               

            //row End
            tData = tData + `
                </tr>
            `;

            //If remainder is .33 create 1 <Td>
            } else if (remainder == 0.33) {
                //Row Start
                tData = tData + `
                    <tr>
                `;

            //Content: <td> <div> <table> <tr> <td> 
            for (var c = (1 + index); c < (2 + index); c++){
                tData = tData + `
                    <td style="width: 33.33%; padding: 0px 25px">
                        <div class="divBorder">
                            <table class="innerTable">
                                <tbody>
                                    <tr>
                                        <td>
                                            <img class="articleImg" src="images/seeking-alpha-badge.png" id="image${c}">

                                        </td>
                                        <td style="padding-left: 5px">
                                            <h3 id="headline${c}"></h3>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>        
                        </div>
                    </td>
                `;

            }               

            //row End
            tData = tData + `
                </tr>
            `;

            //Anything else dont do anything
            } else {
                tData = tData;
            }

            return tData;
        }

        //Inject into the HTML
        newsContainer.appendChild(tbodyHTML);
        //===============================================================
        var red = (JSONData.length + 1)
        console.log(red);

        //Output data to html
        for (var l = 1; l < red; l++){
            console.log("l: " + l);
            spyOutputToHTML(JSONData, l);
        }

    };

    function spyOutputToHTML(data, i) {
        //get current variables in this HTML page x3
        var offset = i - 1;
        var headline = document.getElementById(`headline${i}`);

        //Get Content From the JSON file ex: ".latestPrice"
        var JSONHeadline = data[offset].headline;

        //Inject data into HTML
        headline.innerHTML = JSONHeadline;
    }

    request.send()
</script>

4

1 回答 1

1

首先,干得好!对于 javascript 的新手来说,这是令人印象深刻的工作

很少有事情可以肯定地改进,但我不认为你做错了什么。也许,只是逻辑remainder太混乱了。我打赌应该有更简单的方法

可读性

如果您将视图(模板)逻辑、请求逻辑和数据“按摩”逻辑分开,您的代码无疑会更容易阅读和理解

视图逻辑

通常,“手动”(createElement, appendChild)构建 HTML 结构需要更多的努力,并且可以说更令人困惑,而不是使用模板函数(有点像您所做的)渲染字符串并将结果注入您需要的地方。混合这些方法比“手动”做所有事情更容易出错。所以,我建议你有一个视图/模板函数,它可以获取数据并返回一个字符串

function renderTable(data) {
    var result = '<div>';
    // build the result string...
    result += '</div>';
    return result;
}

// and then...
targetEl.innerHTML = renderTable(data);

您可能还想利用微模板。对于更大的应用程序,一种或另一种模板将是必不可少的。让自己熟悉模板引擎。对于您的项目,使用 javascript 构建字符串很好。虽然,您可以考虑使用更先进的技术

数据“按摩”逻辑

好吧,这归结为让您的模板函数对其上下文不“聪明”(基本的关注点分离),并且只使用数据。不“烹饪”它,只吃它:)

所以,而不是这样做

function renderTable(data) {
    var result = '<div>';
    var something = data.abc * data.xyz;
    // do something with something here
    result += '</div>';
    return result;
}

targetEl.innerHTML = renderTable(data);

... 你来做这件事

function adaptResponsePayloadData(data) {
    var result = { ...data };
    result.something = result.abc * result.xyz;
    return result;
}

function renderTable(data) {
    // ...
}

targetEl.innerHTML = renderTable(adaptResponsePayloadData(data));

这是所谓的适配器设计模式的一个例子。这是使用它的正确案例。还有许多其他设计模式,我强烈建议您花时间熟悉它们

请求逻辑

这里的另一个关注点分离。您可以将请求逻辑放在一个单独的函数中,类似于我们如何将“按摩”从上面的视图中分离出来

const API_ENDPOINT_URL = 'https://api.iextrading.com/1.0/stock/spy/news';

function fetchData(callback) {
    var request = new XMLHttpRequest();
    request.open('GET', API_ENDPOINT_URL);
    request.onLoad(() => {
        var data = JSON.parse(request.responseText);
        callback(data);
    });
    request.send();
}

// ... and then
fetchData(data => {
    // ...
    targetEl.innerHTML = renderTable(adaptResponsePayloadData(data));
});

执行顺序注意事项

当你的代码运行时,有一个经验法则可以让你清楚。这完全是一个挑剔的选择,但是可以在代码级别将内容与何时分开

function goOn() { // there are many conventional names for this, like `main`
    fetchData(data => {
        document.body.innerHTML = renderTable(adaptResponsePayloadData(data));
    });
}

window.onload = goOn;

关于 HTML 和 CSS 的注释

  1. 你真的不需要<tbody>。除非您想使用 CSS 突出显示某些内容,否则不需要它

  2. 避免使用内联样式,例如<td style="width: 33.33%; padding: 0px 25px">. 你可以用 CSS 来表达

  3. 你不需要divBorder上课。向父级添加填充,向td子级添加边框table

其他小笔记

通常,第一个大写字母的名称是对象构造函数或类。简单地说,使常规 var 名称为 lowerCamelCase,例如jsonHeadline

JSON 是我们所知道的表示法术语。当我们解析该符号的字符串时,它就变成了dataor contextData,你知道了……然后,数据里面的内容就变成了headline

尽量命名变量,这样您就不必写注释来理解您的意思。在这里找到其他好的提示

确保您的生产代码没有console.log语句

let关键字比var. 你永远不会用它污染全局范围


请注意,StackExchange 上有 Code Review,您可以在其中学习如何编写出色代码的许多其他方面

你做的真的很棒。祝您旅途愉快!:)

于 2019-02-07T07:13:00.567 回答