2016-04-04 15 views
1

我意識到這可能以前曾以不同的方式提出過,但我還沒有找到適合這種特殊情況的答案,因爲它需要用普通的JS編寫(沒有jQuery )。這是班級任務,所以我無能爲力。使用純javascript從數組中刪除值

基本上我被要求創建一個複選框列表,當點擊時將相關的值發送到一個數組,然後再次單擊以取消選中該框時應刪除所述值。

這樣做的HTML是

  <div> 
       <fieldset class="checks"> 
       <legend><span>What are your favorite JavaScript libraries/frameworks?</span></legend> 
       <input type="checkbox" id="jq" value="jQuery" name="libraries" /> 
       <label for="jq" id="jqLabel">jQuery</label> 
       <input type="checkbox" id="angular" value="AngularJS" name="libraries" /> 
       <label for="angular" id="angularLabel">AngularJS</label> 
       <input type="checkbox" id="node" value="NodeJS" name="libraries" /> 
       <label for="node" id="nodeLabel">NodeJS</label> 
       <input type="checkbox" id="react" value="ReactJS" name="libraries" /> 
       <label for="react" id="reactLabel">ReactJS</label> 
       <input type="checkbox" id="backbone" value="Backbone" name="libraries" /> 
       <label for="backbone" id="backboneLabel">Backbone</label> 
      </fieldset> 
      </div> 

      <p id="testPara"></p> 

和相應的JavaScript我到目前爲止是

// Function for JS library selections 
var libraryArray = []; 

function libraryQuery(event) { 

    if (event === undefined) { // get caller element in IE8 
     event = window.event; 
    } 

    var callerElement = event.target || event.srcElement; 
    var libraryName = callerElement.value; 
    if (callerElement.checked) { 
    libraryArray.push(libraryName); 
    document.getElementById("testPara").innerHTML = libraryArray; 
    } 
    else { 
    var listItems = document.querySelectorAll(".checks input"); 

    for (var i = 0; i < libraryArray.length; i++) { 
     if (listItems[i].value === libraryName) { 
     // remove element at index i from array 
      libraryArray.splice(i, 1); 
      document.getElementById("testPara").innerHTML = libraryArray; 

     } 
    } 
    } 
} 

function createEventListeners() { 
    var libraries = document.getElementsByName("libraries"); 
    if (libraries[0].addEventListener) { 
    for (var i = 0; i < libraries.length; i++) { 
     libraries[i].addEventListener("change", libraryQuery, false); 
    } 
    } else if (libraries[0].attachEvent) { 
    for (var i = 0; i < libraries.length; i++) { 
     libraries[i].attachEvent("onchange", libraryQuery); 
    } 
    } 

} 

if (window.addEventListener) { 
    window.addEventListener("load", createEventListeners, false); 
} else if (window.attachEvent) { 
    window.attachEvent("onload", createEventListeners); 
} 

這種格式基本上是一樣的東西在我的課本用於另一項任務,這在那裏工作,但出於某種原因在這個項目上給了我非常時髦的結果。

對於一個它將添加到數組沒有問題,但有時它會在檢查,取消選中,然後再次檢查後添加相同值的多個副本,這是不好的。

至於刪除時取消選中框,有時它的作品,有時它不。有時它會刪除與當前未選中複選框關聯的值完全不同的值。

我認爲這個問題是在這個for循環中的某個地方,更具體地說,它可能是一個與其中的if語句的問題。但經過大量修補之後,我只是難以解決如何糾正問題(我也可能完全錯誤,因爲錯誤在別的地方)。

for (var i = 0; i < libraryArray.length; i++) { 
    if (listItems[i].value === libraryName) { 
    // remove element at index i from array 
     libraryArray.splice(i, 1); 
     document.getElementById("testPara").innerHTML = libraryArray; 

    } 
} 

任何幫助是真正的讚賞。這是一個jsfiddle

+0

您可能會考慮從陣列中添加和刪除值,因此增加你什麼時候第一次檢查,如果該值在陣列中創建一個單獨的函數,如果是,不添加它再次。類似於刪除:如果該值不在數組中,請不要嘗試刪除它。所以你也可以編寫一個小的* getIndex *函數,或者爲* Array.prototype.indexOf *創建一個polyfill。 – RobG

回答

1

你已經複雜了這一點,你需要做的只是檢查框是否被選中,並且該值不在數組中,然後將其推送到數組,否則只需根據索引刪除它。

function libraryQuery() { 
    var libraryName = this.value, 
     index  = libraryArray.indexOf(libraryName); 

    if (this.checked && index === -1) { 
     libraryArray.push(libraryName); 
    } else { 
     libraryArray.splice(index, 1); 
    } 
    document.getElementById("testPara").innerHTML = libraryArray; 
} 

FIDDLE

+0

謝謝,這個作品。你有沒有注意到我的代碼中有什麼公然錯誤導致了這些問題? – DjH