I am trying to convert jquery into vanilla javascript - javascript

This is probably an easy solution but right now I can't figure out how to make it work
$(".a").click(function () {
if ($("#btnCollapse").css('display')!='none')
$("#btnCollapse").click();
});
Then I tried using vanilla js, I know I am missing something....
var anchor = document.querySelectorAll(".a");
var button = document.querySelectorAll("#btnCollapse");
function collapseNav() {
anchor.addEventListener('click', function() {
button.style.display="none"
});
button.click();
}

querySelectorAll returns a nodelist so you need to loop through its result.
For the #bntCollapse use querySelector, it returns as single element. For elements with an id, and if you need to find many, you can use getElementById, which is faster than querySelector
To get the style, use window.getComputedStyle as it will return a style being set using external CSS as well, which element.style.display won't.
var anchors = document.querySelectorAll(".a");
for (var i = 0; i < anchors.length; i++) {
anchors[i].addEventListener('click', function(e){
var btn = document.querySelector("#btnCollapse");
if (window.getComputedStyle(btn,null).getPropertyValue("display") != 'none') {
btn.click();
}
})
}
Note, you can use foreach to loop the elements, though based on how, in IE, Edge and Safari it might not work, so test it thoroughly, therefore I used a for..loop for maximum browser support.

Direct conversion of your "jQuery" code:
if (button.style.display != 'none')
button.click();

It can be done using closure-in-loop,
var anchor = document.querySelectorAll(".a");
var button = document.querySelectorAll("#btnCollapse");
Array.from(anchor).forEach(a => {
a.addEventListener('click', function() {
if(button.style.display!="none"){
button.click();
}
});
});

querySelectorAll() returns a collection of elements, not a single one, hence you need to loop over it. The button has an id so you can select it using querySelector() to get a single instance back.
You also have no collapseNav() function in the jQuery version so your event handler will be added on load.
Finally the logic is not the same. In the jQuery you only click the button if it's display is not none. Try this:
var anchor = document.querySelectorAll(".a");
var button = document.querySelector("#btnCollapse");
anchor.forEach(function(el) {
el.addEventListener('click', function() {
if (button.style.display != 'none')
button.click();
});
});

Related

converting javascript to jquery function not correctly working

I am trying to convert a small script from javascript to jquery, but I don't know where I should be putting the [i] in jquery?. I am nearly there, I just need someone to point out where I have gone wrong.
This script expands a search input when focused, if the input contains any values, it retains it's expanded state, or else if the entry is removed and clicks elsewhere, it will snap back.
Here is the javascript:
const searchInput = document.querySelectorAll('.search');
for (i = 0; i < searchInput.length; ++i) {
searchInput[i].addEventListener("change", function() {
if(this.value == '') {
this.classList.remove('not-empty')
} else {
this.classList.add('not-empty')
}
});
}
and converting to jquery:
var $searchInput = $(".search");
for (i = 0; i < $searchInput.length; ++i) {
$searchInput.on("change", function () {
if ($(this).value == "") {
$(this).removeClass("not-empty");
} else {
$(this).addClass("not-empty");
}
});
}
Note the key benefit of jQuery that it works on collections of elements: methods such as .on automatically loop over the collection, so you don't need any more than this:
$('.search').on("change", function() {
this.classList.toggle('not-empty', this.value != "");
});
This adds a change event listener for each of the .search elements. I've used classList.toggle as it accepts a second argument telling it whether to add or remove the class, so the if statement isn't needed either.

Add and remove a class in javascript

I'm trying to write a function, to make a visual object come on and off, on and off, as the user clicks on it. Then add a click event listener in the class, called button btn-sauce.
So far my code doesn't work :
function renderWhiteSauce() {
if (element.classList) {
element.classList.toggle("btn-sauce.active");
} else {
var classes = element.className.split(" ");
var i = classes.indexOf("btn-sauce.active");
if (i >= 0)
classes.splice(i, 1);
else
classes.push("btn-sauce.active");
element.className = classes.join(" ");
}
document.querySelector('.btn-sauce.active').addEventListener('click', () => {
state.sauce = !state.sauce;
renderEverything();
});
You can just add and remove classes with methods classList.add('classname') and classList.remove('classname'). Define class which makes btn active and just add or remove it.
const elem = document.querySelector('.btn-sauce')
elem.addEventListener('click', () => {
if(elem.className.indexOf('className') < 0) {
elem.classList.add('className')
} else {
elem.classList.remove('className')
}
});
btn-sauce and active are two separate classes, but you are writing your code like they are one. Remove btn-sauce. (including the dot) from everything above the querySelector line and you will be able to toggle the active class on and off.
If the element is not "active" to begin with, you should also change document.querySelector('.btn-sauce.active') to document.querySelector('.btn-sauce').
One last note, you are calling renderEverything() in your click handler, which I assume is another function that calls renderWhiteSauce(), but I thought I'd mention it in case this was just a typo and they were meant to be the same function.

Toggle Classname using document.getElementsByClassName - JavaScript

I have a left sidebar menu which has submenus, i want each menu item to toggle a classname "active" so the submenu will open i have CSS for it.
The thing is i am using document.getElementsByClassName to select and iterate all of the menu items and is only working for the first element, i have been searching and it has something to do with closures and i am trying different solutions but its not working.
i am making the function so i can use it to toggle a classname of another div and not the one clicked, in that case i use and ID.
var toggleClassname = function (otherDiv, sameDiv) {
var divToToggleClass;
//are we going to use ID and toggle the classname of another div ?
if (sameDiv) {
divToToggleClass = this;
} else {
divToToggleClass = document.getElementById(otherDiv);
}
console.log(divToToggleClass);
var className = divToToggleClass.className + ' ';
if (~className.indexOf(' active ')) {
divToToggleClass.className = className.replace(' active ', '');
} else {
divToToggleClass.className += ' active';
}
};
var MenuItemsArray = document.getElementsByClassName("classOfMyMenuItems");
for (var i = 0; i < subMenuItemsArray.length; i++) {
MenuItemsArray[i].addEventListener('click', function () { toggleClassname(null, true) }, false);
}
i have been trying using [].forEach.call or wrapping the function in another that returns the function, not working.
I am doing this in pure javascript, cant use the new .classList.toggle i would also use attachEvent to be more backwards compatible (old IE).
The problem is that within your toggleClassname() function this is not equal to the clicked element. It will actually be either undefined or window depending on whether your code is running in strict mode or not.
A click handler bound with addEventListener() will have this set to the clicked element, so within the following anonymous function:
function () { toggleClassname(null, true) }
...the value of this is the element in question. But then you call toggleClassname() and don't pass it a reference to the clicked element or set its this value. You can explicitly set it using .call():
function () { toggleClassname.call(this, null, true) }
Further reading:
this in JavaScript
.call()
This answer might help you:
addEventListener using for loop and passing values
Without going too deep into your code, I'd say if you try and make it
for (var i = 0; i < subMenuItemsArray.length; i++) {
(function () {
var k = i;
MenuItemsArray[k].addEventListener('click', function () { toggleClassname(null, true) }, false);
}()); // immediate invocation
}
That should work.

Handling click events for many elements by bubbling

I have a list of controls contained in a parent div called overlay-controls.
There is many list controls that each have their own overlay-controls.
I am using a for loop to add the event listener to each button that contains the class delete.
Before the user can delete the item, they must confirm. I am trying to attach this to every delete button found in overlay-controls.
I got it to work using a for loop but I know there is a better way using bubbling and capturing. I am having trouble targeting only the delete class inside overlay-controls by bubbling up to parent div.
See the live demo here by clicking on each delete button: http://jsfiddle.net/8qqfeoa2/1/
Here is my code using the for loop:
(function() {
function getConfirmation(e){
var retVal = confirm("Are you sure you want to delete this request?");
if( retVal == true ){
return true;
}else{
e.preventDefault();
return false;
}
}
var del = document.querySelectorAll('.delete');
for(var i = 0, len = del.length; i < len; i++){
del[i].addEventListener('click', function(e) {
getConfirmation(e);
}, false);
}
}());
You dont event need the For / .each loop
Jquery takes care of it internally
$('.delete').on('click', function(e){
getConfirmation(e);
});
Provided you are using jQuery and in getConfirmation method you may also get that specific (clicked) element by using e.target which returns the target on which click happened.
Only Javascript solution
As you requested one
var deletebuttons = document.getElementsByClassName('delete');
for(var button in deletebuttons) {
button.onclick = getConfirmation;
}

OnClick or OnHover Event Listen For All IMG in javascript

I have a list of images
I would like to listen for click actions or hover actions on any "img" on my page regarless of ID. And I want to use regular javascript and be friendly with modern browsers.
I have done a lot of research and reading but I have yet to find a solution.
I am thinking that my code might look something like this but I'm not positive:
var allimg = document.getElementsByTagName('img');
for(var i = 0; i < allimg.length; ++i) {
// do something
}
How do I add onlick to this, do I need to call it as a function on pageload? how do I have the javascript react to all img tags when clicked?
Use event delegation:
document.getElementsByTagName('body')[0].onclick = function (event) {
if (event.target.nodeName === "IMG") {
console.log('do something');
}
}
Fiddle
any chance you might have jQuery? If so...
$(img).on('click',function(e){
console.log('rad')
});
otherwise.. you are on the right track. Untested but this should get you there...
function clickHandler(e){
console.log('I love goats')
}
var allimg = document.getElementsByTagName('img');
for(var i = 0; i < allimg.length; ++i) {
allimg[i].onclick = clickHandler;
}
No use adding listeners to every element. Try this inside your loop. allimg[i].onclick/onmouseover = function(){//your code}

Categories