2017-02-19 94 views
0

几个星期前,我开始自学自学JavaScript,并遇到了一个我无法解决的问题。该程序通过允许用户输入保存在数组中并且也在屏幕上显示为li元素的名称列表起作用。然后该程序将随机选择一个输入的人。尝试从列表中删除某人时出现问题。我能够从HTML中删除它们,但不能从数组中删除它们。我试图使用.splice方法,如下所示,但这只会删除数组中的最后一个元素。我相信这是由于indexOf(li.value)不适合这种用途,但不知道还有什么要尝试。任何帮助深表感谢。无法从阵列中移除元素

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Student Randomiser</title> 
    <link rel="stylesheet" href="custom.css"> 
    </head> 
    <body> 
    <h1 id="myHeading">Student Randomiser</h1> 
    <div class="list"> 
     <p class="description">Add Students:</p> 
     <input type="text" class="studentName" value="Write Students Here"> 
     <button class="addStudent">Add student</button> 
     <ul id= "listStudentNames"> 
     </ul> 
     <button class="randomStudent">Select a random student</button> 
</div> 
<script src="randomNamePicker.js"></script> 
</body> 
</html> 




const addStudent = document.querySelector('button.addStudent'); 
const studentName = document.querySelector('input.studentName'); 
const randomStudent = document.querySelector('button.randomStudent'); 
const listStudentNames = document.querySelector("ul"); 
let students = [ 
] 
let number 
window.onload=function(){ 
addStudent.addEventListener('click', addStudentToList); 
randomStudent.addEventListener('click', selectRandomStudent); 
listStudentNames.addEventListener("click", removeStudent); 
} 
function addButtons(li){ 
    let remove =document.createElement('button'); 
    remove.className= "removeStudent"; 
    remove.textContent = "Remove Student"; 
    li.appendChild(remove) 
} 

function removeStudent(){ 
    if (event.target.tagName === "BUTTON") { 
let li = event.target.parentNode; 
let ul = li.parentNode; 
let i = students.indexOf(li.value); 
students.splice(i,1); 
ul.removeChild(li); 
    }} 

function getRandomIntInclusive(min, max) { 
    min = Math.ceil(min); 
    max = Math.floor(max); 
    number = Math.floor(Math.random() * (max - min)) + min; 
} 

function addStudentToList() { 
    students.push(studentName.value); 
    var ul = document.getElementById("listStudentNames"); 
    var li = document.createElement("li"); 
    li.appendChild(document.createTextNode(studentName.value)); 
    addButtons(li); 
    ul.appendChild(li); 
    studentName.value = ""; 
} 

function selectRandomStudent(){ 
getRandomIntInclusive(0, students.length); 
alert(students[number]); 
} 
+0

你有没有调试呢?有没有控制台错误? “我”的价值是什么? – Carcigenicate

+0

你确定你的功能正在引发吗?你有没有关于按钮点击事件的事件监听器?如果是这样,我会建议在这里添加它们。另外,通过注释来记录代码的哪些部分属于哪些文件会很有帮助。 –

+0

@MikeLawson无控制台错误。我附上了整个代码,希望能够更容易理解。道歉,如果它是一团糟,正如我刚才提到的,我刚刚开始,所以把它放在一起对我来说是一个挑战。 –

回答

0

有各种各样的与您的代码的问题,有些是计划性的,有些是文体,有些是你的逻辑。

您的主要问题是具有value属性的唯一元素是表单元素。所以,当你写:

let i = students.indexOf(li.value); 

因为你设置li最多是event.target父节点您有一个问题。 event.target是启动事件的元素,在这种情况下为<button>,并且按钮的父级为<div>,它(再次)没有value属性,并且不是正确的元素。

此值是您根据您的splice。相反,您需要在li元素或数组的列表中获取li的索引位置(它们应该是相同的)。

接下来,在这种情况下,首先你并不需要数组,因为所有的学生姓名都是<ul>元素中的元素,这意味着他们可以通过“节点列表“,它是一个支持length属性的”类似数组“的对象,是可枚举和可索引的。将<li>元素内容保留在同步数组中不会在此处添加任何值,并使整个任务更加复杂,因为您必须将HTML列表与数组保持同步。

说了这一切,这就是你正在尝试什么,有评论直列解释为什么我的代码与你不同的工作示例。

// When the DOM is loaded and all elements are accessible... 
 
window.addEventListener("DOMContentLoaded", function(){ 
 

 
    // Get references to the DOM elements needed to solve problem 
 
    // Using "var" here is perfectly acceptable as their scope will 
 
    // be the entire parent function, which is what we want. Get all 
 
    // these references just once so we don't have to keep scanning 
 
    // the DOM for them each time we want to work with the list. Also, 
 
    // name your variables "noun"-like names when they refer to elements 
 
    var btnAdd = document.querySelector(".addStudent"); 
 
    var btnRandom = document.querySelector(".randomStudent"); 
 
    var list = document.getElementById("listStudentNames"); 
 
    var student = document.querySelector("input[type='text']"); 
 
    var output = document.querySelector(".report"); 
 
    
 
    // Set up an empty array to keep the synchronized student list in 
 
    var students = []; 
 

 
    // Set up click event handling functions 
 
    btnAdd.addEventListener("click", addStudent); 
 
    btnRandom.addEventListener("click", getRandomStudent); 
 
    
 
    function addStudent(){ 
 
    // Make sure there was valid input 
 
    if(student.value.trim() === ""){ return; } 
 
    
 
    // Create a new <li> element 
 
    var li = document.createElement("li"); 
 
    
 
    // Set new element up with a click event handler that will 
 
    // cause the current element to be removed from the list 
 
    li.addEventListener("click", removeStudent); 
 
    
 
    // Populate the element with the text from the <input> 
 
    // The element gets raw text set with the .textContent property 
 
    // while content of form elements is gotten with the "value" 
 
    // property 
 
    li.textContent = student.value; 
 
    
 
    // Update the list id's to match the array indexes 
 
    sync(); 
 
    
 
    // Add the element to the end of the <ul>'s list elements 
 
    list.appendChild(li); 
 
    
 
    // Add new student to the array: 
 
    students.push(student.value); 
 
    
 
    // Clear value from input 
 
    student.value = ""; 
 
    
 
    logResults(); 
 
    } 
 

 
    function getRandomStudent(){ 
 
    console.clear(); 
 
    
 
    if(students.length){ 
 
     // Use the built-in JavaScript Math object to get a random number 
 
     // between 0 (inclusive) and 1 (exclusive) then multiply that 
 
     // number by the lenght of the <li> node list to get a random 
 
     // number between 0 and the amount of elements in the array 
 
     var random = Math.floor(Math.random() * list.children.length); 
 
     console.log("Random student is: " + list.children[random].textContent); 
 
    } else { 
 
     console.log("No students to choose from!"); 
 
    } 
 
    } 
 

 
    function removeStudent (evt){ 
 
    
 
    // Re-sync the indexes of the HTML elements to match the array 
 
    sync(); 
 
    
 
    // Remove corresponding student from array first... 
 
    console.clear(); 
 
    console.log("Student " + evt.target.id + " about to be removed"); 
 
    students.splice(+evt.target.id, 1); 
 
    
 
    // Every event handling function automatically gets a reference 
 
    // to the event that triggered the function sent into it. We can 
 
    // access that event to get a reference to the actual DOM object 
 
    // the caused the event to be triggered with "event.target" 
 
    list.removeChild(evt.target); 
 
    
 
    logResults(); 
 
    } 
 
    
 
    // We have to keep the HTML element indexes in sync with the array indexes 
 
    function sync(){ 
 
    // Loop through the HTML elements and give them an id that corresponds 
 
    // to the index position of its counterpart in the array. 
 
    Array.prototype.forEach.call(list.children, function(el, index){ 
 
     el.id = index; 
 
    }); 
 
    } 
 
    
 
    // This is just a function for updating the display to show the contents 
 
    // of the array to confirm that it is in sync with the list 
 
    function logResults(){ 
 
    output.innerHTML = "Array now contains: <br>" + students.join("<br>"); 
 
    } 
 

 
});
.list, .report { float:left; } 
 
.report { background-color:aliceblue; }
<div class="list"> 
 
    <input type="text" class="studentName" placeholder="Enter Student Name Here"> 
 
    <button class="addStudent">Add student to list</button> 
 
    <ul id= "listStudentNames"> 
 
    </ul> 
 
    <p class="description">(Click on a student to remove them from the list.)</p> 
 
    <button class="randomStudent">Select a random student</button> 
 
</div> 
 
<div class="report"></div>