#javascript #html #css #class
#javascript #HTML #css #класс
Вопрос:
У меня есть несколько <li>
тегов под <ul>
в моем HTML-коде. Они <li>
оформлены с помощью CSS для создания карточек с заголовком и описанием.
Я создал кнопку с прослушивателем событий, в которой я хочу создать новый <li>
элемент под <ul>
тегом в HTML, когда я нажимаю кнопку.
Я извлекаю <ul>
и пытаюсь appendChild()
создать новый <li>
. Это все в классе в JS. Я не уверен, почему новые <li>
карточки не отображаются при нажатии кнопки.
```
class DOMHelper {
static clearEventListeners(element) {
const clonedElement = element.cloneNode(true);
element.replaceWith(clonedElement);
return clonedElement;
}
//receives element ID and a New destination in the DOM and sends the
//card to that destination Via Append.
static moveElement(elementId, newDestinationSelector) {
const element = document.getElementById(elementId);
const destinationElement =
document.querySelector(newDestinationSelector);
destinationElement.append(element);
}
}
class Tooltip {}
class ProjectItem {
constructor(id, updateProjectListsFunction, type) {
this.id = id;
this.updateProjectListsHandler = updateProjectListsFunction;
this.connectMoreInfoButton();
this.connectSwitchButton(type);
}
connectMoreInfoButton() {}
//retreives the button of the given DOM element and adds an event
//listener to it that executes updateProjectListHandler
//recieves from: update () {}
//runs updateProjectListsHandler --> this.switchProject -->
connectSwitchButton(type) {
const projectItemElement = document.getElementById(this.id);
let switchBtn = projectItemElement.querySelector('button:last-of-
type');
switchBtn = DOMHelper.clearEventListeners(switchBtn);
switchBtn.textContent = type === 'active' ? 'Finish' : 'Activate';
switchBtn.addEventListener(
'click',
this.updateProjectListsHandler.bind(null, this.id)
);
}
update(updateProjectListsFn, type) {
this.updateProjectListsHandler = updateProjectListsFn;
this.connectSwitchButton(type);
}
}
class ProjectList {
projects = [];
constructor(type) {
//selects all of the li elements under the `#${type}-projects DOM
//element depending on the element input type
//and creates a new ProjectItem for every li element it found.
this.type = type;
const prjItems = document.querySelectorAll(`#${type}-projects
li`);
for (const prjItem of prjItems) {
this.projects.push(
new ProjectItem(prjItem.id, this.switchProject.bind(this),
this.type)
);
}
//new DayOfWeek('Monday');
console.log(this.projects);
}
setSwitchHandlerFunction(switchHandlerFunction) {
this.switchHandler = switchHandlerFunction;
}
//pushes project to the projects array. Project input is "new
//ProjectList('finished');"
addProject(project) {
this.projects.push(project);
DOMHelper.moveElement(project.id, `#${this.type}-projects ul`);
project.update(this.switchProject.bind(this), this.type);
}
//finds every project id in projects with the id matching constant
//projectId
//filters out every dom object with id that does not equal the
//projected input to the function
switchProject(projectId) {
// const projectIndex = this.projects.findIndex(p => p.id ===
projectId);
// this.projects.splice(projectIndex, 1);
this.switchHandler(this.projects.find(p => p.id === projectId));
this.projects = this.projects.filter(p => p.id !== projectId);
console.log('Testing this button')
}
switchDayHandler() {
const selectDayOfWeek = document.getElementById('p4');
//const dayOfWeek = selectDayOfWeek.querySelector('li')
selectDayOfWeek.addEventListener(
'click',
this.updateDayInfoHandler()
);
console.log(selectDayOfWeek);
}
updateDayInfoHandler () {
console.log('TEST TEST TEST');
}
}
class DayOfWeek {
projectList = {
monday: [
{
title: 'test',
description: "test"
}
]
}
constructor(day) {
this.createNewButton;
switch (day) {
case ( 'Monday' ):
//this.addNewListItemHandler();
break;
case ( 'Tuesday' ):
console.log('Tuesday');
break;
case ( 'Wednesday' ):
console.log('Wednesday');
break;
case ( 'Thursday' ):
console.log('Thursday');
break;
case ( 'Friday' ):
console.log('Friday');
break;
//default:
// ingredient = null;
}
}
addNewListItemHandler() {
const projectItem = document.getElementById('active');
const newListItem = document.createElement('li');
newListItem.innerHTML = `id="p2"
data-extra-info="Not really a business topic but still
important."
class="card"
>
<h2>MONDAY ITEM</h2>
<p>Don't forget to pick up groceries today.</p>
<button class="alt">More Info</button>
<button>Finish</button>
`;
projectItem.appendChild(newListItem);
}
createNewButton() {
const newButton = document.getElementById('addButton');
newButton.addEventListener( 'click', this.addNewListItemHandler);
}
}
class App {
static init() {
const activeProjectsList = new ProjectList('active');
const finishedProjectsList = new ProjectList('finished');
activeProjectsList.setSwitchHandlerFunction(
finishedProjectsList.addProject.bind(finishedProjectsList)
);
finishedProjectsList.setSwitchHandlerFunction(
activeProjectsList.addProject.bind(activeProjectsList)
);
}
}
App.init();
```
<body>
<header id="main-header">
<h1>Project Planner</h1>
</header>
<div>
<section id="days-projects">
<header>
<h2>Days</h2>
</header>
<ul>
<li
id="p4"
data-extra-info="Super important conference! Fictional but
still!"
class="card"
>
<h2>Monday</h2>
</li>
<li
id="p5"
data-extra-info="Super important conference! Fictional but
still!"
class="card"
>
<h2>Tuesday</h2>
</li>
<li
id="p6"
data-extra-info="Super important conference! Fictional but
still!"
class="card"
>
<h2>Wednesday</h2>
</li>
<li
id="p7"
data-extra-info="Super important conference! Fictional but
still!"
class="card"
>
<h2>Thursday</h2>
</li>
<li
id="p8"
data-extra-info="Super important conference! Fictional but
still!"
class="card"
>
<h2>Friday</h2>
</li>
</ul>
</section>
<section id="active-projects">
<header>
<h2>Active Projects</h2>
</header>
<ul id = 'active'>
<li
id="p1"
data-extra-info="Got lifetime access, but would be nice to
finish it soon!"
class="card"
>
<h2>Finish the Course</h2>
<p>Finish the course within the next two weeks.</p>
<button class="alt">More Info</button>
<button>Finish</button>
</li>
<li
id="p2"
data-extra-info="Not really a business topic but still
important."
class="card"
>
<h2>Buy Groceries</h2>
<p>Don't forget to pick up groceries today.</p>
<button class="alt">More Info</button>
<button>Finish</button>
</li>
</ul>
</section>
<section id="finished-projects">
<header>
<h2>Finished Projects</h2>
</header>
<ul>
<li
id="p3"
data-extra-info="Super important conference! Fictional but
still!"
class="card"
>
<h2>Book Hotel</h2>
<p>
Academind conference takes place in December, don't forget to
book a hotel.
</p>
<button class="alt">More Info</button>
<button>Activate</button>
</li>
</ul>
</section>
</div>
<button id = "addButton" class='add_Button'>ADD NEW</button>
< /body>
</html>
```css
* {
box-sizing: border-box;
}
html {
font-family: sans-serif;
}
body {
margin: 0;
}
#main-header {
width: 100%;
height: 6rem;
display: flex;
justify-content: center;
align-items: center;
background: #a3d2ca;
}
#main-header h1 {
color: white;
margin: 0;
}
footer {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
text-align: center;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
margin: 1rem 0;
}
section {
margin: 1rem auto;
width: 40rem;
max-width: 90%;
height: 100%;
border-radius: 10px;
}
section ul {
padding: 1rem;
max-height: 30rem;
overflow: scroll;
}
.Days {
padding: 1rem;
max-height: 20rem;
background: #d49a89;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
/*border: 1px solid #ff0062;*/
margin: 0;
}
section > h2 {
color: white;
margin: 0;
border-radius: 10px;
}
button {
font: inherit;
background: #f7d1ba;
color: white;
border: 1px solid #f7d1ba;
padding: 0.5rem 1.5rem;
cursor: pointer;
}
button.alt {
background: white;
color: #ff0062;
}
button:focus {
outline: none;
}
button:hover,
button:active {
background: #f7d1ba;
border-color: #5eaaa8;
color: white;
}
.card {
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
padding: 1rem;
background: white;
}
#active-projects {
border: 2px solid #d49a89;
margin: 10px;
width: 30%;
border-radius: 10px;
}
#active-projects > header {
background: #d49a89;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
#active-projects header h2 {
color: white;
margin: 0;
}
#finished-projects {
border: 2px solid #d49a89;
margin: 10px;
width: 30%;
border-radius: 10px;
}
#finished-projects > header {
background: #d49a89;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
#finished-projects header h2 {
color: white;
margin: 0;
border-radius: 10px;
}
div {
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: center;
height: 35rem;
}
#days-projects {
border: 2px solid #d49a89;
margin: 10px;
width: 30%;
border-radius: 10px;
}
#days-projects > header {
background: #d49a89;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
#days-projects header h2 {
color: white;
margin: 0;
}
#days-projects li:hover {
background: #5eaaa8;
}
.add_Button {
align-items: center;
border: solid red;
}
```
Комментарии:
1. вы создаете другой
<li></li>
внутри<li>
тега?2. Пожалуйста, добавьте HTML и CSS, связанные с этим — возможно, это центральная проблема
3. Хорошо, я добавлю. Спасибо! и если кажется, что я создаю другой <li> внутри <li>, то это не мое намерение. Я просто хочу создать его в <ul>
4. Вы где-нибудь создаете экземпляр класса DayOfWeek?
5. Нет, я не такой? Где было бы правильное место для этого? Я думаю, что это может быть проблемой…
Ответ №1:
Похоже, что может возникнуть несколько проблем (как упоминает @CodeCreate, вы добавляете li внутри li, и я не уверен, почему вы дважды вызываете createNewButton), но я подозреваю, что основная проблема, о которой вы спрашиваете, связана с вашим вызовом addEventListener.
Вам нужно передать addEventListener функцию для запуска при срабатывании события.
Вы пытаетесь передать this.addNewListItemHandler, но поскольку вы добавили круглые скобки в его конце, вы немедленно вызываете функцию, а не подключаете ее к запуску при нажатии кнопки.
Попробуйте переписать свой метод createNewButton как:
newButton.addEventListener( ‘click’, this.addNewListItemHandler );
Комментарии:
1. Я пытался использовать newButton.addEventListener( ‘click’, this.addNewListItemHandler ); но это все равно не сработало. Я буду продолжать пытаться. Это странно … даже если я попытаюсь что-то console.log() вместо вызова функции на кнопке… это все еще не работает
Ответ №2:
Попробуйте создать экземпляр класса после его определения:
пусть DaysOfWeek = новый DaysOfWeek
Вероятно, для начала это не обязательно должен быть класс, но поскольку это скорее дизайнерское решение, я оставлю это для вас, чтобы исследовать и решить.
Комментарии:
1. Мне также было интересно, должен ли он быть в классе. Я использовал классы для практики ООП, но это может быть случай, когда это не нужно, я попробую вашу рекомендацию. Спасибо!