Почему добавление стиля с помощью JavaScript не работает

#javascript #html #css #ecmascript-6

Вопрос:

Я новичок и сейчас изучаю JavaScript. Я пытаюсь создать проект javascript. В этом проекте я пытаюсь добавить стиль с помощью javascript. В моем проекте есть кнопка (метка привязки) с именем «Закрыть». Когда он щелкнет, стиль text-decoration: line-through будет добавлен к описанию, которое является идентификатором issue-{id} . Но стиль не работает. Стиль не добавляется, когда я нажимаю кнопку «Закрыть».

Посмотрите на код javascript в строке № 29 и 53.

Вот мой полный код:

 document.getElementById('issueInputForm').addEventListener('submit', submitIssue);

let issueCounterEl = document.getElementById("issue-counter");

function submitIssue(e) {
    const getInputValue = id => document.getElementById(id).value;
    const description = getInputValue('issueDescription');
    const severity = getInputValue('issueSeverity');
    const assignedTo = getInputValue('issueAssignedTo');
    const id = Math.floor(Math.random() * 100000000)   '';
    const status = 'Open';
    const issue = { id, description, severity, assignedTo, status };
    let issues = [];
    if (localStorage.getItem('issues')) {
        issues = JSON.parse(localStorage.getItem('issues'));
    }
    issues.push(issue);
    localStorage.setItem('issues', JSON.stringify(issues));
    document.getElementById('issueInputForm').reset();
    fetchIssues();
    e.preventDefault();
}

const closeIssue = id => {
    const issues = JSON.parse(localStorage.getItem('issues'));
    const currentIssue = issues.find(issue => issue.id == id);
    currentIssue.status = 'Closed';
    
    document.getElementById(`issue-${id}`).style.textDecoration = 'line-through'; // This line - line: 29. Id form line: 53

    localStorage.setItem('issues', JSON.stringify(issues));
    fetchIssues();
}

const deleteIssue = id => {
    const issues = JSON.parse(localStorage.getItem('issues'));
    const remainingIssues = issues.filter(issue => issue.id != id)
    localStorage.setItem('issues', JSON.stringify(remainingIssues));
    fetchIssues();
}

const fetchIssues = () => {
    const issues = JSON.parse(localStorage.getItem('issues'));
    const issuesList = document.getElementById('issuesList');
    issuesList.innerHTML = '';

    for (var i = 0; i < issues.length; i  ) {
        const { id, description, severity, assignedTo, status } = issues[i];

        issuesList.innerHTML  = `<div class="well">
                              <h6>Issue ID: ${id} </h6>
                              <p><span class="label label-info"> ${status} </span></p>
                              <h3 id="issue-${id}"> ${description} </h3> 
                              <p><span class="glyphicon glyphicon-time"></span> ${severity}</p>
                              <p><span class="glyphicon glyphicon-user"></span> ${assignedTo}</p>
                              <a href="#" onclick="closeIssue(${id})" class="btn btn-warning">Close</a>
                              <a href="#" onclick="deleteIssue(${id})" class="btn btn-danger">Delete</a>
                              </div>`;
    }
    issueCounterEl.innerText = issues.length;
} 
 <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Issue Tracker: </title>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body onload="fetchIssues()">
    <div class="container">
        <h1>Issue Tracker: <span id="issue-counter"></span></h1>
        <div class="jumbotron">
            <h3>Add New Issue:</h3>
            <form id="issueInputForm">
                <div class="form-group">
                    <label for="issueDescription">Description</label>
                    <input type="text" class="form-control" id="issueDescription" placeholder="Describe the issue ...">
                </div>
                <div class="form-group">
                    <label for="issueSeverity">Severity</label>
                    <select id="issueSeverity" class="form-control">
                        <option value="Low">Low</option>
                        <option value="Medium">Medium</option>
                        <option value="High">High</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="issueAssignedTo">Assigned To</label>
                    <input type="text" class="form-control" id="issueAssignedTo" placeholder="Enter responsible ...">
                </div>
                <button type="submit" class="btn btn-primary">Add</button>
            </form>
        </div>
        <div class="col-lg-12">
            <div id="issuesList"></div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"
        integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
        integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
        crossorigin="anonymous"></script>
    <script src="main.js"></script>
</body>

</html> 

В инструментах разработки Chrome нет предупреждений или ошибок.

Как я могу решить эту проблему?

Комментарии:

1. Вы устанавливаете новый стиль, а затем вызываете fetchIssues() программу, которая воссоздает HTML со всеми новыми элементами, заменяющими тот, которому вы только что присвоили стиль. Когда вы назначаете стиль определенному элементу, а не стилю, который применяется через таблицу стилей, этот стиль применяется только к этому конкретному элементу. При замене элемента новым элементом предыдущие настройки стиля, заданные вручную, не будут применены к этому новому элементу.

Ответ №1:

Ваш код в порядке, но в нем есть небольшая ошибка. Все, что вам нужно сделать, это просто поставить строку document.getElementById(`issue-${id}`).style.textDecoration = 'line-through'; после fetchIssues(); .

Тогда это будет выглядеть так:

 const closeIssue = id => {
    const issues = JSON.parse(localStorage.getItem('issues'));
    const currentIssue = issues.find(issue => issue.id == id);
    currentIssue.status = 'Closed';
    localStorage.setItem('issues', JSON.stringify(issues));
    fetchIssues();
    document.getElementById(`issue-${id}`).style.textDecoration = "line-through";
}
 

Ответ №2:

  1. Это происходит потому, что вы добавляете идентификатор не на тот элемент, он должен быть включен <h6> , и вы его включаете <h3> .
  2. Прокомментируйте свой метод выборки, потому что он переопределит стиль, который вы только что применили.

См. скрипку: https://jsfiddle.net/ramseyfeng/41kvwqye/

 issuesList.innerHTML  = `<div class="well">
                              <h6 id="issue-${id}">Issue ID: ${id} </h6>
                              <p><span class="label label-info"> ${status} </span></p>
                              <h3> ${description} </h3> 
                              <p><span class="glyphicon glyphicon-time"></span> ${severity}</p>
                              <p><span class="glyphicon glyphicon-user"></span> ${assignedTo}</p>
                              <a href="#" onclick="closeIssue(${id})" class="btn btn-warning">Close</a>
                              <a href="#" onclick="deleteIssue(${id})" class="btn btn-danger">Delete</a>
                              </div>`;
 

Комментарии:

1. О, прости. Идентификатор h3 сбивает вас с толку. Я установил его для h3 , а не для h6 . Если я прокомментирую метод выборки, стиль применяется правильно, но внутренний текст h6 не изменяет форму, открытую для закрытия.

2. Где находится текст? Я вижу, что статус изменился с «Открыто» на «Закрыто» после нажатия кнопки «Закрыть». Пожалуйста, внимательно проверьте предыдущую скрипку.

Ответ №3:

Вы не можете увидеть эффект сквозного удара в пользовательском интерфейсе, потому что вы всегда отображаете информацию из настройки локального хранилища. Вы не обновляете эффект «удар через стиль» в информации о вашем локальном хранилище. Поэтому, прежде чем извлекать вашу информацию, обновите информацию о локальном хранилище для определенного идентификатора с помощью эффекта сквозного стиля, как показано ниже.

Вместо

 document.getElementById(`issue-${id}`).style.textDecoration = 'line-through'; // This line - line: 29. Id form line: 53
 

Используйте ниже

 issues.find(issue => issue.id == id).style.textDecoration = 'line-through';
 

В приведенной выше строке будет обновлено значение локального хранилища, и вы можете увидеть эффект в пользовательском интерфейсе.

 document.getElementById('issueInputForm').addEventListener('submit', submitIssue);

let issueCounterEl = document.getElementById("issue-counter");

function submitIssue(e) {
    const getInputValue = id => document.getElementById(id).value;
    const description = getInputValue('issueDescription');
    const severity = getInputValue('issueSeverity');
    const assignedTo = getInputValue('issueAssignedTo');
    const id = Math.floor(Math.random() * 100000000)   '';
    const status = 'Open';
    const issue = { id, description, severity, assignedTo, status };
    let issues = [];
    if (localStorage.getItem('issues')) {
        issues = JSON.parse(localStorage.getItem('issues'));
    }
    issues.push(issue);
    localStorage.setItem('issues', JSON.stringify(issues));
    document.getElementById('issueInputForm').reset();
    fetchIssues();
    e.preventDefault();
}

const closeIssue = id => {
    const issues = JSON.parse(localStorage.getItem('issues'));
    const currentIssue = issues.find(issue => issue.id == id);
    currentIssue.status = 'Closed';    
    issues.find(issue => issue.id == id).style.textDecoration = 'line-through';

    localStorage.setItem('issues', JSON.stringify(issues));
    fetchIssues();
}

const deleteIssue = id => {
    const issues = JSON.parse(localStorage.getItem('issues'));
    const remainingIssues = issues.filter(issue => issue.id != id)
    localStorage.setItem('issues', JSON.stringify(remainingIssues));
   fetchIssues();
}

const fetchIssues = () => {
    const issues = JSON.parse(localStorage.getItem('issues'));
    const issuesList = document.getElementById('issuesList');
    issuesList.innerHTML = '';

    for (var i = 0; i < issues.length; i  ) {
        const { id, description, severity, assignedTo, status } = issues[i];

        issuesList.innerHTML  = `<div class="well">
                              <h6>Issue ID: ${id} </h6>
                              <p><span class="label label-info"> ${status} </span></p>
                              <h3 id="issue-${id}"> ${description} </h3> 
                              <p><span class="glyphicon glyphicon-time"></span> ${severity}</p>
                              <p><span class="glyphicon glyphicon-user"></span> ${assignedTo}</p>
                              <a href="#" onclick="closeIssue(${id})" class="btn btn-warning">Close</a>
                              <a href="#" onclick="deleteIssue(${id})" class="btn btn-danger">Delete</a>
                              </div>`;
    }
    issueCounterEl.innerText = issues.length;
} 
 <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Issue Tracker: </title>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body onload="fetchIssues()">
    <div class="container">
        <h1>Issue Tracker: <span id="issue-counter"></span></h1>
        <div class="jumbotron">
            <h3>Add New Issue:</h3>
            <form id="issueInputForm">
                <div class="form-group">
                    <label for="issueDescription">Description</label>
                    <input type="text" class="form-control" id="issueDescription" placeholder="Describe the issue ...">
                </div>
                <div class="form-group">
                    <label for="issueSeverity">Severity</label>
                    <select id="issueSeverity" class="form-control">
                        <option value="Low">Low</option>
                        <option value="Medium">Medium</option>
                        <option value="High">High</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="issueAssignedTo">Assigned To</label>
                    <input type="text" class="form-control" id="issueAssignedTo" placeholder="Enter responsible ...">
                </div>
                <button type="submit" class="btn btn-primary">Add</button>
            </form>
        </div>
        <div class="col-lg-12">
            <div id="issuesList"></div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"
        integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
        integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
        crossorigin="anonymous"></script>
    <script src="main.js"></script>
</body>

</html> 

Ответ №4:

Ваш JavaScript запускается до завершения визуализации, поэтому вам нужно подождать, пока он будет завершен, и вы сделаете это с помощью

 window.addEventListener('DOMContentLoaded', (event) => {
    console.log('DOM fully loaded and parsed');
/// add code here
});
 

Ответ №5:

Просто небольшой совет: (не собираюсь решать вашу проблему) Установите другую переменную в качестве элемента:

 issueid = document.getElementById(`issue-${id}`)
 

Затем выполните следующие действия:

 issueid.style.textDecoration = 'line-through';
 

(Я знаю, что это должно быть в комментариях, но у меня недостаточно репутации.)

Ответ №6:

Попробуйте это

 document.getElementById(`issue-${id}`).style.textDecoration = "line-through";