2014-03-06 50 views
0

我已經發布了這個,但我認爲我的問題很難解釋。我有多個「彈出編輯」類的div。
我希望能夠使用getElementsByClassName來定位這些目標.....結果是帶有一些輸入字段的彈出窗口。請參閱下面的代碼。
我知道getElementsByClassName返回一個包含EditQuestion類的所有元素的數組,但是我沒有寫出一個可以使用這個數組的函數。我缺乏技巧(我是新手)。
有人可以給我解決方案,所以我有我可以學習的東西。爲直接詢問答案而抱歉...我嘗試了許多事情而沒有成功。
非常感謝GetElementsByClassName - 不能寫函數來使用返回的數組

HTML

<button class="EditQuestion">Edit</button> 
    <div class="overlay2"></div> 
    <div class="popupEdit"> 
    <h2>Edit Question, some input box here..</h2> 
    <button class="CloseBtn2">Close</button> 
    </div> 

JS

 window.onload = function() { 

     document.getElementsByClassName("EditQuestion").onclick = function() { 
     var overlay2 = document.getElementsByClassName("overlay2"); 
     var popupEdit = document.getElementsByClassName("popupEdit"); 
     overlay2.style.display = "block"; 
     popupEdit.style.display = "block"; 
     }; 

     document.getElementsByClassName("CloseBtn2").onclick = function() { 
     var overlay2 = document.getElementsByClassName("overlay2"); 
     var popupEdit = document.getElementsByClassName("popupEdit"); 
     overlay2.style.display = "none"; 
     popupEdit.style.display = "none"; 
     }; 
    }; 

CSS

 button.EditQuestion{ 
     padding: 0; 
     border: none; 
     background: none; 
     color:#A8A8A8; 
     font-weight: bold; 
     } 

     button.CloseBtn2 { 
     padding: 0; 
     border: none; 
     background: none; 
     position:absolute; 
     right:10px; 
     top:5px; 
     } 

     .popupEdit { 
     display:none; 
     position:fixed; 
     left:40%;   
     top:30%;   
     width:600px;  
     height:150px; 
     margin-top:-75px; 
     margin-left:-150px; 
     background:#FFFFFF; 
     border:1px solid #000; 
     z-index:100000;  
     } 

    .overlay2 { 
     display:none;  
     position:fixed; 
     left:0px;   
     top:0px;   
     width:100%;  
     height:100%;  
     background:#000; 
     opacity:0.5;  
     z-index:99999; 
    } 

編輯的版本 - 我曾嘗試使用querySelectorAll由TJ克羅德所建議的.... querySelector可以工作,但是當我在for循環中添加並更改爲querySelectorAll時,它會失敗....任何建議

window.onload = function() { 

document.querySelectorAll(".EditQuestion").onclick = function() { 
var overlay2 = document.querySelectorAll(".overlay2"); 
var popupEdit = document.querySelectorAll(".popupEdit"); 
var index; 
     for (index = 0; index < overlay2.length; ++index) { 
     overlay2[index].style.display = "none"; 
     popupEdit[index].style.display = "block"; 
    } 
}; 

document.querySelectorAll(".CloseBtn2").onclick = function() { 
    var overlay2 = document.querySelectorAll(".overlay2"); 
    var popupEdit = document.querySelectorAll(".popupEdit"); 
    var index; 
     for (index = 0; index < overlay2.length; ++index) { 
     overlay2[index].style.display = "none"; 
     popupEdit[index].style.display = "block"; 
    } 
}; 

};

+0

是否要得到數組來自'classname'的元素? –

+0

「EditQuestion」類的div在哪裏?我只看到一個按鈕,那個階級。 –

+0

道歉....是的,我的意思是很多彈出編輯類 – GhostRider

回答

3

getElementsByClassName(在它存在的瀏覽器上)返回列表,而不是單個元素。所以這條線和類似的:

overlay2.style.display = "none"; 

...失敗,因爲該列表沒有style屬性。

如果你只是想處理第一的比賽,你可以通過[0]抓住它:

overlay2[0].style.display = "none"; 

(這將如果有沒有比賽,失敗雖然)。或者,由於getElementsByClassName ISN 「T以及支持爲querySelector,你可能更喜歡:

overlay2 = document.querySelector(".overlay2"); // Gives you the first match; note the dot 
overlay2.style.display = "none"; 

或者,如果你想通過所有這些循環,你需要一個循環:

var index; 
for (index = 0; index < overlay2.length; ++index) { 
    overlay2[index].style.display = "none"; 
} 

以獲取列表爲循環,要麼使用getElementsByClassName,你目前(但它不會對IE8的工作),或使用querySelectorAll(將):

overlay2 = document.querySelectorAll(".overlay2"); // Gives you a list 

你能告訴我如何將這個循環合併到JS函數中嗎?

我不認爲你想要一個循環;你只是想處理特定的覆蓋和與按鈕相關的彈出窗口,對吧?

我可能會稍微改變HTML使每個組都有一個組股利或周圍的類似:

<div class="question"><!-- Wrapper div for each question --> 
    <button class="EditQuestion">Edit</button> 
    <div class="overlay2" style="display: none"></div><!-- Note I've hidden ... --> 
    <div class="popupEdit" style="display: none">  <!-- ...these by default --> 
     <h2>Edit Question, some input box here..</h2> 
     <button class="CloseBtn2">Close</button> 
    </div> 
</div> 

...和使用事件委派:

var container = document.getElementById("questions"); 
hookEvent(container, "click", function(event) { 
    var button, group, overlay, display; 

    // Find the button that was clicked, if any 
    button = event.target; 
    while (button && (
      button.tagName.toUpperCase() !== "BUTTON" || 
      !button.className.match(/\bEditQuestion\b|\bCloseBtn2\b/) 
     )) { 
     button = button.parentNode; 
    } 
    if (button) { 
     // One of our desired buttons was clicked, find the parent 
     group = button.parentNode; 
     while (group && !group.className.match(/\bquestion\b/)) { 
      group = group.parentNode; 
     } 
     if (group) { 
      overlay = group.querySelector(".overlay2"); 
      display = overlay.style.display === "block" ? "none" : "block"; 
      overlay.style.display = display; 
      group.querySelector(".popupEdit").style.display = display; 
     } 
    } 
}); 

...其中hookEvent看起來是這樣的:

function hookEvent(element, eventName, handler) { 
    if (element.addEventListener) { 
     element.addEventListener(eventName, handler, false); 
    } else if (element.attachEvent) { 
     element.attachEvent("on" + eventName, function(event) { 
      var e = event || window.event; 
      if (!e.target) { 
       e.target = e.srcElement; 
      } 
      handler.call(element, e); 
     }); 
    } else { 
     throw "addEventListener or attachEvent required"; 
    } 
} 

Live Example | Source

關於事件委託的好處是,由於您在容器上處理事件,所以添加或刪除容器中的問題的次數並不重要,它只是繼續工作。

上面的很多代碼是處理IE的古怪事件,並處理事件委託。 FWIW,一個好的DOM庫可以讓你更簡單。這裏有一個jQuery的例子:

$("selector for the container").on("click", ".EditButton, .CloseBtn2", function() { 
    var button = $(this); 
    button.closest('.question').find(".overlay2, .popupEdit").toggle(button.is(".EditButton")); 
}); 
+0

感謝您的迴應。你能告訴我如何將這個循環合併到JS函數中嗎?這是我遇到問題的部分。本質上,當頁面打開時會有許多'編輯問題按鈕',我希望用戶能夠點擊其中的任何一個並激活彈出式窗口.....非常感謝您對「勺子」需求的幫助和道歉餵食'在這.... – GhostRider

+0

@GhostRider:我已經更新了答案,我可能根本不會使用循環。 –

+0

太棒了...我要研究你的答案並嘗試一下。非常感謝所有這些工作。我會讓你知道它是怎麼回事... – GhostRider

1

getElementsByClassName回報節點列表的HTMLCollection

document.getElementsByClassName("EditQuestion")[0].onclick = function() { //<-- get the first (and only?) element from the list 
+0

它實際上是一個_NodeList_或_HTMLCollection_,它們是_Array-like_但不是_Arrays_。 –

+0

好的,謝謝你的輸入。我會糾正這一點。 – alexP

0

如果你想使用getElementsByClassName來獲得,數組中的所有元素與該類則:

這是類似下面:

var els = document.getElementsByClassName("myclass"); 

Array.prototype.forEach.call(els, function(el) { 
// Do stuff with the element 
console.log(el.tagName); 
}); 

// Or optionally 
[].forEach.call(els, function() {...}); 

下由蒂姆回答getElementsByClassName

0

下面是一個示例工作代碼,供您開始使用— http://jsfiddle.net/vVq7E/1

也學會使用以下getElementsByClassName,這是在此代碼中使用addEventListenernextElementSiblingelement.style

<div class='modules'> 
    <button class='edit'>Edit</button> 
    <div class='overlay'> 
     <p>Hello!</p> 
     <button class='close'>Close</button> 
    </div> 
</div> 
... 


window.onload = function init() { 
    modules = document.getElementsByClassName('modules'); 
    len = modules.length; 
    var i = 0; 
    for (; i < len; i++) { 
     modules[i].getElementsByClassName('edit')[0].addEventListener('click', showOverlay); 
     modules[i].getElementsByClassName('close')[0].addEventListener('click', hideOverlay); 
    } 
} 

function showOverlay() { 
    this.nextElementSibling.style.display = 'block'; 
} 

function hideOverlay() { 
    var overlays = document.getElementsByClassName('overlay'); 
    for (var i = 0; i < len; i++) { 
     if (overlays[i].style.display === 'block') { 
      overlays[i].style.display = 'none'; 
      return; 
     }  
} 


.modules { 
    /*optional!*/ 
    margin:10px; 
} 
.overlay { 
    position:absolute; 
    width:100%; 
    height:100%; 
    top:0; 
    left:0; 
    display:none; 
    /*optional!*/ 
    padding:20px; 
    /*optional!*/ 
    background:yellow; 
}