GetElementsByClassName - 无法编写函数来使用返回的数组

时间:2014-03-06 10:51:08

标签: javascript getelementsbyclassname

我已经发布了这个,但我认为我的问题解释得很差。我有多个具有“popupEdit”类的div。我希望能够使用getElementsByClassName来定位这些...结果是带有一些输入字段的弹出窗口。请参阅下面的代码。
我知道getElementsByClassName返回一个包含EditQuestion类的所有元素的数组,但是我没能编写一个可以使用这个数组的函数。我缺乏技巧(我是新手)。
有人可以给我解决方案,所以我可以学习一些东西。直接问答案的道歉......我尝试了很多事情但没有成功。非常感谢

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;   
    }

编辑版本 - 我试图使用TJ Crowder建议的querySelectorAll .... 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";
    }
};

};

4 个答案:

答案 0 :(得分:3)

getElementsByClassName(在存在的浏览器上)返回列表,而不是单个元素。所以这一行和类似的:

overlay2.style.display = "none";

...失败,因为列表没有style属性。

如果您只想处理第一次匹配,可以通过[0]抓取它:

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

(如果没有匹配,则会失败。)或者,由于getElementsByClassName不像querySelector那样受支持,您可能更喜欢:< / p>

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或类似的组合:

<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"));
});

答案 1 :(得分:1)

getElementsByClassName返回 NodeList HTMLCollection

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

答案 2 :(得分: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 () {...});

Tim Down在getElementsByClassName

上的回答

答案 3 :(得分:0)

以下是您开始使用的示例工作代码 - http://jsfiddle.net/vVq7E/1

还要学会使用以下getElementsByClassNameaddEventListener,{{1此代码中使用的{},nextElementSibling

element.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;
        }    
 }