最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - How to get index of an array element in click event with JavaScript - Stack Overflow

programmeradmin4浏览0评论

I'm developing an Electron App, and for this specific part of the code, it's necessary that I recover the index of the current element (on click).

HTML:

<div>
    <input type="checkbox" class="optionBox"> Minimize to tray after 10 seconds
    <input type="checkbox" class="optionBox"> Always check day transition
</div>

JavaScript:

modifierCheckboxes = document.querySelectorAll('.optionBox');

for (var i = 0; i < modifierCheckboxes.length; i++) {
    modifierCheckboxes[i].addEventListener('click', function (e) {
        bindModifierCheckBoxes(e);
    });
}

function bindModifierCheckBoxes(e) {
    // I need the reference for modifierCheckboxes[i] here 
}

I've tried this:

function bindModifierCheckBoxes(e){
    var t=e.target;
    console.log(Array.prototype.indexOf.call(t.parentNode.childNodes,t));
}

It came "close", but when I click on the first checkbox, I get index of 1, and in the second one I get 3.

Please, no external libraries, just plain JavaScript.

I'm developing an Electron App, and for this specific part of the code, it's necessary that I recover the index of the current element (on click).

HTML:

<div>
    <input type="checkbox" class="optionBox"> Minimize to tray after 10 seconds
    <input type="checkbox" class="optionBox"> Always check day transition
</div>

JavaScript:

modifierCheckboxes = document.querySelectorAll('.optionBox');

for (var i = 0; i < modifierCheckboxes.length; i++) {
    modifierCheckboxes[i].addEventListener('click', function (e) {
        bindModifierCheckBoxes(e);
    });
}

function bindModifierCheckBoxes(e) {
    // I need the reference for modifierCheckboxes[i] here 
}

I've tried this:

function bindModifierCheckBoxes(e){
    var t=e.target;
    console.log(Array.prototype.indexOf.call(t.parentNode.childNodes,t));
}

It came "close", but when I click on the first checkbox, I get index of 1, and in the second one I get 3.

Please, no external libraries, just plain JavaScript.

Share Improve this question edited Nov 16, 2019 at 22:40 Rick Stanley asked Jan 20, 2017 at 2:49 Rick StanleyRick Stanley 8502 gold badges13 silver badges25 bronze badges 3
  • BTW, [].indexOf is a shorter version of Array.prototype.indexOf – John Hascall Commented Jan 20, 2017 at 2:58
  • @JohnHascall my advice would be to stay away from .indexOf because it is not cross-browswer compatible. There are other, safer JavaScript methods to check for string literals, etc. .match() and .test() respectively acheives what .indexOf() does and is cross-browser compatible. – Alexander Dixon Commented Jan 20, 2017 at 3:44
  • Yes, IE<9 is stupid. If you have to care, you have my pity. – John Hascall Commented Jan 20, 2017 at 3:50
Add a comment  | 

8 Answers 8

Reset to default 9

Maybe you can convert the Object selector to an array and then you can use an indexOf.

var checks = document.querySelectorAll('.optionBox');

checks.forEach(function(check){
  check.addEventListener('click', checkIndex);
})

function checkIndex(event){
  console.log( Array.from(checks).indexOf(event.target) );
}

Make use of closures:

modifierCheckboxes = document.querySelectorAll('.optionBox');

modifierCheckboxes.forEach(function(checkbox, i) {
    checkbox.checked = customConf[i];;
    checkbox.addEventListener('click', function (e) {
        bindModifierCheckBoxes(e, i);
    });
});

function bindModifierCheckBoxes(e, index) {
    // index is passed inside the event listener function
}

use .children instead of .childNodes ... .children gives a list of child Elements excluding text nodes

in HTML, when you nicely format your source, there's text nodes between > and < that don't (usually) effect the rendering of the page

function bindModifierCheckBoxes(e) {
    var t=e.target;
    var checkboxes = t.parentNode.getElementsByClassName('optionBox');
    console.log(Array.prototype.indexOf.call(checkboxes, t) + 1);
}

Here is a fiddle: https://jsfiddle.net/7p3gsy75/

Another option would be to give your checkboxes id's (here I chose lame ones):

<div>
  <input type="checkbox" id="cb1" class="optionBox"> Minimize to tray after 10 seconds
  <input type="checkbox" id="cb2" class="optionBox"> Always check day transition
</div>

and then look at e.target.id

You can use change instead of click:

$('.optionBox').on('change', function() {
    $(this).each(function() {
        if (this.checked) {
            alert($(this).index());
        } else {
            alert("unchecked");
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
      <input type="checkbox" class="optionBox"> Minimize to tray after 10 seconds
      <input type="checkbox" class="optionBox"> Always check day transition
  </div>

Pass modifierCheckboxed[i] to your bindModifierCheckBoxes function. So you send the référence of the current checkbox then you can do what you want with it.

Here is another suggestion that will work on pages where additional check boxes might be added later on.

// Things might become dynamic on your page ...
const div=document.querySelector("div");
document.querySelectorAll("button").forEach(b=>b.addEventListener("click",ev=>div.insertAdjacentHTML(ev.target.textContent,'<label><input type="checkbox" class="optionBox"> A new option box!</label>')));

// This will always show the correct index number of your checkbox:
div.addEventListener("click",ev=>{
 if(ev.target.matches(".optionBox")){
  const o=ev.target.closest("label");
  console.log(`changed optionBox ${[...div.querySelectorAll("label:has(.optionBox)")].indexOf(o)+1}.`);
}})
  
label {display:block}
<button>afterbegin</button>
<div><div>
 Some text before we start.
<label><input type="checkbox"> This checkbox should not be counted and not trigger anything.</label>
<label><input type="checkbox" class="optionBox"> Minimize to tray after 10 seconds</label>
<label><input type="checkbox" class="optionBox"> Always check day transition</label>
 And some text at the end.
</div></div>
<button>beforeend</button>

The general idea is to work with delegated click event handling and to re-establish the list of applicable check boxes after each click.

发布评论

评论列表(0)

  1. 暂无评论