Getting index from Javascript array [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
How would I get the index of the chosen element or of 'elems[i]' within the javascript? I know this is a very simple question so any suggestions on a book to buy or course to take would be greatly appreciated. Thanks!
code:
<html>
<body>
<table>
<tr id="subject"><?php
$subjects = array("IT","Programming","Networks");
foreach($subjects as $key => $value) {
echo "<td>"."<a href='index.php' class='column'>".$value."</a>"."</td>";
}
?></tr>
</table>
</body>
<script type="text/javascript">
var elems = document.getElementsByClassName('column');
for (var i = 0; i < elems.length; i++) {
elems[i].onclick = function () {
console.log(this.innerHTML);
};
}
</script>

var elems = document.getElementsByClassName('column');
for (var i = 0; i < elems.length; i++) {
let a=i;//the magic happens
elems[i].onclick = function () {
console.log(a);
};
}
See Closures, let, ES6.
Option two (for older browsers):
var elems = document.getElementsByClassName('column');
for (var i = 0; i < elems.length; i++) {
(function(){
var a=i;
elems[i].onclick = function () {
console.log(a);
};
})();
}
You need to put the index into the handlers scope, either trough using block scoping (let, first answer) or by creating a new scope trough an IIFE...
(You need to create an own scope for each handler)
solution 3:
set the dom objects id:
elems[i].id=i;
elems[i].onclick=function(){
alert(this.id);
};
Solution 4:
Get the index dynamically:
alert(elems.indexOf(this));

Related

How I find the position of an HTML element [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
I am working on a project where I need to find the position of a "div" element, relative to the other divs (index position). for example if I have a div of class "item" and below it a div of class "list", the "item" would have an index value of 0, and the "list" would have an index value of 1.
I need help in finding the divs index.
I also need to use vanilla javascript without any library and no jQuery
I would share the code but unfortunatly, I write the program on an air gapped system. so I cannot post the code here.
You can fetch all divs and iterate the List. Check if contains the classes item or list and push to an array the index.
for example like that:
const d = document.querySelectorAll('div');
let r = [];
for(let i = 0; i < d.length; i++) {
if (d[i].classList.contains('item')) {
r.push({'itemIndex': i});
}
if (d[i].classList.contains('list')) {
r.push({'listIndex': i});
}
};
console.log(r)
<div class="a">A</div>
<div class="x">X</div>
<div class="item">ITEM</div>
<div class="list">LIST</div>
<div class="y">Y</div>
After much digging I found this post: JavaScript DOM: Find Element Index In Container
which my answer is based of (note the objects are inside a div called wit a class of "side-bar" and the amount of divs is saved in a global variable called sidebar_len)
var element1 = el_in; //the function gets "this" for the event
var sidebar = document.getElementsByClassName("side-bar")[0];
var sidebar_divs = sidebar.getElementsByTagName("div");
var div_index = 0;
var is_same = false;
while(div_index < sidebar_len && is_same == false) {
is_same = sidebar_divs[div_index].isSameNode(element1);
div_index++
}
div_index--;
const index = (start, find) => {
const sEl = document.getElementsByClassName(start)[0];
const el = document.getElementsByClassName(find)[0];
const childrens = [...el.parentElement.children];
const sIndex = childrens.indexOf(sEl);
for (let i = sIndex - 1; i >= 0; i--) {
childrens.splice(i, 1);
}
return childrens.indexOf(el);
};
const startClsName = 'item';
console.log('item index', index(startClsName, 'item'));
console.log('list index', index(startClsName, 'list'));
<div class='first'></div>
<div class='second'></div>
<div class='item'></div>
<div class='list'></div>

jQuery.each() function in plain (vanilla) javascript [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
$.fn.slideUpTransition = function() {
return this.each(function() {
var $el = $(this);
$el.css("max-height", "0");
$el.addClass("height-transition-hidden");
});
};
In jQuery, this.each will iterate over all the matching elements and then apply the function. Here this as a global object holds the class selectors of a div.
jQuery.fn.init [div.custom-dropdown-body.height-transition,
prevObject: jQuery.fn.init(1)]
How can we achieve the same with pure javascript?
I tried doing following but couldn't get as expected:
var obj = this;
for(var i=0; i< obj.length; i++){
// codes
};
return this
Here's a NodeList based example for how $.each works:
NodeList.prototype.each = function(fn) {
for (var i = 0; i < this.length; i++) {
fn.apply(this[i], [i, this[i]]);
}
return this;
};
document.querySelectorAll("p").each(console.log).each(function(i) {
this.textContent = i;
});
<p></p>
<p></p>
<p></p>
(Using the same order of index, element that jQuery uses, as opposed to the JS convention of element, index!)
Edit: added binding of correct this for callback

What is the difference between `for` and `while` loops in my Script [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a JavaScript function that collects a number of input tags into an array and then decides if one of them has been selected:
function validateAnswerSelected () {
var formValid = false;
var groupedInput = document.getElementsByName("choice");
var i;
// while (!formValid && i < questions[questionNumber].choices.length) {
// if (groupedInput[i].checked) {
// formValid = true;
// }
// i++;
// }
// for (i = 0; questions[questionNumber].choices.length; i++) {
// if (groupedInput[i].checked) {
// formValid = true;
// }
// }
if (!formValid) {
alert("select an answer");
}
}
When I uncomment the while loop the function works correctly. However when I uncomment the for loop groupedInput becomes undefined.
What is the difference here?
Edit: when I uncomment the while then I do initialise the i variable. The error I made in the question is just a typo.
Typo:
for (i = 0; questions[questionNumber].choices.length; i++) {
Should be:
for (i = 0; i < questions[questionNumber].choices.length; i++) {
// ^ You forgot the `i <`
You didn't assign a value for "i" before using a while loop.
Blockquote var i; //default is undefined
But, in for loop you have assigned inside of that.
Blockquote for (i = 0; questions[questionNumber].choices.length; i++) {
That's why it returns undefined.
Sollution:
var i = 0;
Now it works fine. :)

Undefined var error in an array iteration on a page using mootools [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
var makeModelYearSelect = document.getElementById("<%= MakeModelYearFilterLB.ClientID %>").control;
var selectedMakeModelYearItems = makeModelYearSelect.get_checkedItems();
var selectedMakeModelYearItemIds = [];
for (var index = 0; index < selectedMakeModelYearItems.length; index++) {
selectedMakeModelYearItemIds.push(selectedMakeModelYearItem[index].get_value(index));
}
Why is this firing back an error of Microsoft JScript runtime error: 'selectedMakeModelYearItem' is undefined?
Mootools won't let me use a simple for...in for iterations.
I've looked at it 6 ways to Sunday so what the heck am I missing?
Because selectedMakeModelYearItem is undefined.
selectedMakeModelYearItems isn't, though.
Maybe you try to call this code berofe page is loaded. In this case select tag that you try to access don't rendered and cannot be accessed from JavaScript. You can try something like
window.addEventListener("load",
(function() {
return function setMakeModelYearFilter() {
var makeModelYearSelect = document.getElementById("<%= MakeModelYearFilterLB.ClientID %>").control;
var selectedMakeModelYearItems = makeModelYearSelect.get_checkedItems();
var selectedMakeModelYearItemIds = [];
for (var index = 0; index < selectedMakeModelYearItems.length; index++) {
selectedMakeModelYearItemIds.push(selectedMakeModelYearItem[index].get_value(index));
}
window.removeEventListener('load', setMakeModelYearFilter, false);
}})()
, false);

Is there any way to optimise this code? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have a piece of code which will invert all the checkboxes on my form. I have multiple elements (not just checkboxes but also <input type='text'>'s) in it. The reason I need it to be optimised is because it takes about two to three seconds to select all the checkboxes (275 right now).
Here's my code:
function FormInverse() {
var iCheckbox = 1; // Because there are multiple input elements, we need to distinquish the input element ID and the row id
var FormLength = document.FormFacturen.elements.length;
for (i=0; i < FormLength; i++) {
var FormElementType = document.FormFacturen.elements[i].type;
if (FormElementType == "checkbox") {
var Elements = document.getElementsByClassName('row' + iCheckbox); // Alle elementen in de array zetten
var iNumElements = Elements.length;
for (iElement=0; iElement < iNumElements; iElement++) {
if (document.FormFacturen[i].checked == true) {
Elements[iElement].className = "invoice-tr-standard row" + iCheckbox;
} else {
Elements[iElement].className = "invoice-tr-clicked row" + iCheckbox;
}
}
iCheckbox++;
document.FormFacturen[i].checked = !document.FormFacturen[i].checked;
}
}
}
And here is the document.getElementsByClassName function:
document.getElementsByClassName = function(cl) {
var retnode = [];
var myclass = new RegExp('\\b'+cl+'\\b');
var elem = document.getElementsByTagName('*');
for (var i = 0; i < elem.length; i++) {
var classes = elem[i].className;
if (myclass.test(classes)) retnode.push(elem[i]);
}
return retnode;
};
I would suggest using jQuery as well.
Try this:
Add a reference to jQuery:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript" language="JavaScript"></script>
Use this code:
$(':checkbox').each( function() {
$(this).attr('checked', !$(this).attr('checked'));
});
Edited:
Or use this to change the classes as well:
$(':checkbox').each(function() {
var checked = $(this).attr('checked');
if (checked) {
$(this).attr('checked', false);
$(this).addClass('invoice-tr-clicked');
$(this).removeClass('invoice-tr-standard');
}
else {
$(this).attr('checked', true);
$(this).addClass('invoice-tr-standard');
$(this).removeClass('invoice-tr-clicked');
}
});
Final version:
$('#FormFacturen :checkbox').each(function() {
var checked = $(this).attr('checked');
if (checked) {
$(this).attr('checked', false);
$(this).parents('tr').addClass('invoice-tr-clicked');
$(this).parents('tr').removeClass('invoice-tr-standard');
}
else {
$(this).attr('checked', true);
$(this).parents('tr').addClass('invoice-tr-standard');
$(this).parents('tr').removeClass('invoice-tr-clicked');
}
});
Each call to getElementsByClassName is expensive, and it is being called on each pass of your for loop.
In addition to #Geoff's suggestion, you could call document.getElementsByTagName('input'); just once, instead of each time getElementsByClassName is called and cache the result for use within your loop.
That would require making a small modification to your getElementsByClassName function whereby it accepts an array of elements to search through.
document.getElementsByClassName = function(cl, eles) {
var retnode = [];
var myclass = new RegExp('\\b'+cl+'\\b');
var len = eles.length;
for (var i = 0; i < len; i++) {
var classes = eles[i].className;
if (myclass.test(classes)) retnode.push(eles[i]);
}
return retnode;
};
function FormInverse() {
// cache all inputs
var inputs = document.getElementsByTagName("input");
...
// later
var Elements = document.getElementsByClassName('row' + iCheckbox, inputs);
You should look into a library like JQuery. It will handle this kind of thing well.
There are a lot of little things you can do to improve your code though. First thing I notice is that your getElementsByClassName function is looping through ALL elements on your page every time you call it. You could change this line:
var elem = document.getElementsByTagName('*');
to just get the input elements:
var elem = document.getElementsByTagName('input');
I am pretty much sure the bottleneck here is the getElementsByClassName function, the browser needs to re-scan the whole html each time to find your element. I suggest you give your elements a unique id id="row1", id="row2", ... instead of a unique class name and use getElementById which is much faster.
var Elements = document.getElementsById('row' + iCheckbox);

Categories

Resources