2017-02-19 17 views
0

私は数週間前に自分自身でJavaScriptを自己学習し始め、解決できない問題に遭遇しました。このプログラムは、ユーザーが配列に保存された名前のリストを入力できるようにすることによって機能し、画面上にli要素としても表示されます。プログラムはランダムに入力された人の1人を選択します。私の問題は、リストから人を削除しようとしたときに発生します。 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

あなたがそれをデバッグがありますか?コンソールにエラーがありますか? 'i'の値は何ですか? – Carcigenicate

+0

機能が呼び出されていますか?ボタンクリックイベントでイベントリスナーがありますか?もしそうなら、私はここにそれらを追加することをお勧めします。また、コードのどの部分がコメントを介してどのファイルに属しているかを文書化すると便利です。 –

+0

@MikeLawsonコンソールエラーはありません。私はコード全体を添付していますので、理解しやすくなることを願っています。私が言いましたように、混乱している場合はお詫びします。私はちょうどこれをまとめることが私にとって挑戦でした。 –

答えて

0

コードにはさまざまな問題がありますが、プログラムによっては問題があり、一部は文法的であり、一部はロジックです。

あなたの主な問題は、valueプロパティを持つ唯一の要素がフォーム要素であることです。だから、あなたが書くとき:あなたはevent.targetの親ノードであることをliを設定しているため

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

あなたは問題があります。 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>

関連する問題