Как мне упростить этот код?Есть ли лучший способ сделать это? - PullRequest
0 голосов
/ 07 февраля 2019

Я только что получил этот код после нескольких часов стресса.Я новичок в Javascript, поэтому я не уверен, что сделал это наиболее эффективным способом.Я использую API, предоставленный IEX.Цель этого кода - выводить новости, когда они есть.Как вы можете сказать, это не совсем работает, но заголовок заработал.Так что, если я делаю что-то не так, дайте мне знать, пожалуйста.

<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>

1 Ответ

0 голосов
/ 07 февраля 2019

Прежде всего, отличная работа! Это впечатляющая работа для новичка в javascript

Мало что можно улучшить, но я не вижу, что вы делаете что-то не так.Может быть, только логика с remainder слишком запутана.Могу поспорить, что должен быть более простой способ

Удобочитаемость

Ваш код, несомненно, будет легче читать и понимать, если бы у вас была логика представления (шаблонизации), логика запросаи разделенная логика «массирования» данных

Логика представления

Как правило, построение HTML-структур «вручную» (createElement, appendChild) занимает большеусилия и, возможно, более запутанно, чем рендеринг строки с функцией шаблона (вроде как вы сделали) и вставка результата туда, где он вам нужен.Смешивание этих подходов еще более подвержено ошибкам, чем выполнение всего «вручную».Поэтому я хотел бы предложить вам одну функцию представления / шаблона, которая будет принимать данные и возвращать строку

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

Другие мелкие заметки

Условно имена с первой заглавной буквойбуквы являются конструкторами объектов или классами.Просто сделайте обычные имена переменных lowerCamelCase, например jsonHeadline

JSON - это термин для обозначения, которое мы знаем.Когда мы анализируем строку этой нотации, она просто становится data или contextData, вы получаете это ... Тогда, что внутри этих данных становится просто headline

Делайте все возможное для именования переменных, чтобычто вам не нужно писать комментарии, чтобы понять, что вы имели в виду.Найдите другие полезные советы здесь

Убедитесь, что в вашем производственном коде нет console.log операторов

let, которое безопаснее ключевого слова var.Вы никогда не загрязните глобальную область видимости этим


Обратите внимание, что на StackExchange есть Проверка кода, где вы можете узнать много других аспектов написания хорошего кода

Ты отлично справился.Удачи вам в вашем путешествии!:)

...