Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
I want to write a vanilla js function that works like jQuery's addClass() function. I have written the code below.
function checkType(value){ //get type of target
var name = "";
var type = value.split("");
for(var i=1; i<type.length; i++){
name = name + type[i];
}
if(type[0] == "#"){ //if id
return document.getElementById(name); //return id
}else if(type[0] == "."){ //if class
return document.getElementsByClassName(name); //return class
}else{
return null;
}
}
function classesToArray(value){
if(value != null){
value = value.split(" ");
return value;
}
return [];
}
function addClass(target, value) {
var element = checkType(target);
var classes = classesToArray(value);
if(element != null){
classes.forEach(function(classItem){
if(element.length){
for(var i = 0; i < element.length; i++){
element[i].className += " " + classItem;
}
}else{
element.className += " " + classItem;
}
});
}
}
So the way to use it is as below
addClass('.elementIdName','nameOfClassToAdd'); //target Id if begin with .
addClass('#elementClassName','nameOfClassToAdd'); //target className if begin with #
addClass('.elementIdName', 'nameOfClass1 nameOfClass2'); //you can also add multiple class names
The code works. But I know there's a lot of room to improve it. I'd really appreciate if someone could show me the ropes on what should I look for to improve this. Thanks
There is no need to write your own addClass function.
You can use this:
let el = document.querySelector("#your_element_id");
if(el) {
el.classList.add("your class name");
}
source: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
Related
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 4 years ago.
Improve this question
[Ask]
anyone know the reference for a case like this?
the user must type the word: "learn" -> total character 5
while the user types instead: "l3arn"
well I want to count the right word only, so the result 4
from google not yet find a solution, maybe someone knows the keyword/reference for the problem.
I want to implement it in javascript
You want to calculate the number of characters in the correct position?
In that case, it's a simple solution.
Javascript example:
function countCorrectCharacters(expectedString, string) {
var count = 0;
var l = Math.min(expectedString.length, string.length);
for (var i = 0; i < l; ++i) {
if (expectedString[i] === string[i]) {
++count;
}
}
return count;
}
var str = "learn";
var userInput = "l3arn";
var userInputArray = userInput.split('');
var counter = 0;
for(var i = 0; i< "l3arn".lenth(); i++){
if(str.indexOf(userInputArray[i]) !== -1) counter++;
}
If I understand correctly you want to count the number of letters in a string? Use this:
function getNumberOfLetters(string) {
let match = string.match(/[A-Za-z]/g);
return (match && match.length) || 0;
}
console.log(getNumberOfLetters("learn")); // 5
console.log(getNumberOfLetters("l3arn")); // 4
console.log(getNumberOfLetters("12345")); // 0
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 8 years ago.
Improve this question
Can anybody give me the brief explanation of the return statement in the given javascript code.
Please you should see my fiddle : http://jsfiddle.net/m6mxdt9u/
function isPrime(value) {
if (!isPrime.answers)
isPrime.answers = {};
if (isPrime.answers[value] != null) {
return isPrime.answers[value];
}
var prime = value != 1; // 1 can never be prime
for (var i = 2; i < value; i++) {
if (value % i == 0) {
prime = false;
break;
}
}
return isPrime.answers[value] = prime;
}
assert(isPrime(5), "5 is prime!");
assert(isPrime.answers[5], "The answer was cached!");
function assert(value, desc) {
var resultsList = document.getElementById("results");
if (!resultsList) {
resultsList = document.createElement('ul');
document.getElementsByTagName('body')[0].appendChild(resultsList);
resultsList.setAttribute('id', 'results');
}
var li = document.createElement("li");
li.className = value ? "pass" : "fail";
li.appendChild(document.createTextNode(desc));
resultsList.appendChild(li);
}
I struggled in this line :
return isPrime.answers[value];
What will be the return value of the above code and where does it go?
If you're asking about this particular part of the code:
if (isPrime.answers[value] != null) {
return isPrime.answers[value];
}
Then it'll return whether value is prime or not, based on the cached value (value saved on the answers hash). It'll be the value returned by the isPrime function.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I feel like there is too much repetitive code going on here. All I am doing is doing a basic regex match for a string in the URL. If a match is found, I find an li with a class (.index, .grid, .type) and add the active class. This is just for my main nav in an attempt to make it some what dynamic. However, I feel like there is a more efficient way to code this. Any help is greatly appreciated.
$( document ).ready(function() {
var myLocation = window.location;
var convertURL = new String(myLocation);
var index = /index/i;
var grid = /grid/i;
var type = /type/i;
var urlIndex = convertURL.match(index);
var urlGrid = convertURL.match(grid);
var urlType = convertURL.match(type);
if(urlIndex) {
$('.index').addClass('active');
}else if(urlGrid) {
$('.grid').addClass('active');
}else if(urlType) {
$('.type').addClass('active');
}
});
$(function(){
["index", "grid", "type"].forEach(function(term){
if(new RegExp(term, "i").test(location.href))
$("." + term).addClass("active");
});
});
$(document).ready(function () {
// use single var per function, good for minimizing and other stuff
var
i,
// new string literal, not String object
convertURL = '' + window.location,
// the array of strings keeps only the difference from the repetitive code
classes = ['index', 'grid', 'type'],
// using functions with proper arguments reduces repetitivness
matches = function (regex) {
return convertURL.match(new RegExp(regex, 'i'));
}
// var
;
// always use += instead of ++ -> makes for clear intention
for (i = 0; i < classes.length; i += 1) {
if (matches(classes[i])) {
// returning out of this function stops iteration
return $('.' + classes[i]).addClass('active');
}
}
});
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. :)
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);