Rewrite jQuery function to Vanilla JS and optimize - javascript

First I want to apologize, because I am a bit newbie with JS and it's library jQuery. Basically I have written a javascript function that toggles my hamburger menu:
const menuToggle = document.querySelector('.menu-toggle');
let menuOpen = false;
menuToggle.addEventListener('click', () => {
if(!menuOpen) {
menuToggle.classList.add('open');
menuOpen = true;
} else {
menuToggle.classList.remove('open');
menuOpen = false;
}
});
Now I want to rewrite this jQuery function to Vanilla JS
$(function() {
$('.toggle').on('click', function() {
$('.inner-wrapper').toggleClass('open');
});
});
I tried this, but it is not working:
var searchElement = document.createElement(".inner-wrapper");
document.querySelector(".toggle").appendChild(searchElement);
searchElement.addEventListener("open", handleClick);
I would like to combine both functions if possible. Thanks in advance!

First, this code of yours:
menuToggle.addEventListener('click', () => {
if(!menuOpen) {
menuToggle.classList.add('open');
menuOpen = true;
} else {
menuToggle.classList.remove('open');
menuOpen = false;
}
});
can be simplified to this:
menuToggle.addEventListener('click', () => {
menuToggle.classList.toggle('open');
menuOpen = !menuOpen;
});
Second, the equivalent vanilla JavaScript version of this:
$(function() {
$('.toggle').on('click', function() {
$('.inner-wrapper').toggleClass('open');
});
});
is this:
document.querySelector('.toggle').addEventListener('click', function () {
document.querySelector('.inner-wrapper').classList.toggle('open');
});
Finally, this code of yours has problems:
var searchElement = document.createElement(".inner-wrapper");
document.querySelector(".toggle").appendChild(searchElement);
searchElement.addEventListener("open", handleClick);
There is no HTML element called ".inner-wrapper". You probably wanted to create an element with that class, something like this:
var searchElement = document.createElement("div"); // or any valid tag name
searchElement.className = 'inner-wrapper';
Also, there's no event called "open". You probably want that to be "click", and you probably want to target that to the ".toggle" element (not the '.inner-wrapper' element).

Try this,
searchElement.addEventListener("click", handleClick);
And your current code will add a event listener to inner-wrapper class instead of toggle class.
The javascript representation of your jQuery code has to be something like this
document.querySelector('.toggle').addEventListener('click', function(){
document.querySelector('.inner-wrapper').classList.toggle('open');
})

Related

How to make menu close before redirecting to website section

I have a JQuery working code that is closing the navigation before redirecting to the right section. I want to change it for pure javascript. Do you have any ideas how to make it happen? I've searched many topics but didn't find it.
$(document).ready(function() {
$('.menu-mobile a').click(function(e) {
e.preventDefault();
closeNav();
setTimeout(() => {
const nextPage = e.currentTarget.href;
window.location.href = nextPage;
},1000) // set the time here in milliseconds
})
});
Additionally, I would like to change $(document).ready to javascript.
Is it valid replacer?
document.addEventListener("DOMContentLoaded", function() {
//code
});
For example, something like following, you just need closeNav(); function.
document.querySelector(".link").addEventListener("click", function(e) {
e.preventDefault();
console.log(e.target.href)
//closeNav();
setTimeout(() => {
const nextPage = e.target.href;
window.location.href = nextPage;
}, 2000)
});
<div class=".menu-mobile ">
<a class="link" href="https://www.google.com/">link</a>
</div>
you don't need to use $(document).ready in vanilla / pure javascript.
Porting the same logic implemented above in js would be something like this:
HTML
<button click=handleClick(e)>click me </button>
JS
const handleClick = (e) => {
// To prevent event bubbling
e.preventDefault();
window.location.href = e.currentTarget.href
}
Are you asking for your jQuery code to be written in vanilla JS? If so:
document.addEventListener("DOMContentLoaded", function() {
document.querySelector('.menu-mobile a').addEventListener("click", function(e) {
e.preventDefault();
closeNav();
setTimeout(() => {
const nextPage = e.currentTarget.href;
window.location.href = nextPage;
}, 1000); // set the time here in milliseconds
});
});
I used querySelector and addEventListener

Vanilla JS equivalent to jQuery $.once()?

Working on a Drupal 9 site and trying to add some custom JS code to a page.
Drupal.behaviors.syfyGlobalHideMenu = {
attach: function (context, settings) {
$('.nav-flyout', context).once('remove-modals', function () {
$(document).keyup(function (e) {
if (e.keyCode == 27) {
$('.nav-flyout', context).removeClass('js-flyout-active');
}
});
});
}
};
Wondering if there's a vanilla JS equivalent to the jQuery .once functionality above?
Currently Drupal attaches the event listener multiple times and I am trying to avoid that as I only want to attach the event listener once but have it remain attached and run every time the event is invoked.
let intervalID = null;
const search = document.querySelector(".call-us-table input#edit-search");
search.addEventListener("keydown", event => {
form.setAttribute("onsubmit", "return false");
clearInterval(intervalID);
});
search.addEventListener("keyup", event => {
intervalID = setInterval(submitForm, 2000);
});
Jquery once adds an html attribute to check if is the first time to run.
function vanillaOnce() {
if (!document.body.getAttribute('data-once')) {
document.body.setAttribute('data-once', 'true');
return true;
} else {
return false;
}
}
if (vanillaOnce) {
console.log('runs only once');
}

Event listener not firing on click

I am creating a simple function to close a flash message div on click event, but my listener is not firing.
I wrote 3 different functions to try to get it working, but nothing is happening and Chrome console isnt telling me anything.
My first was in ES6 class style, this one:
class closeFlashMessages {
constructor () {
this.getFlashMessages = document.querySelector("#flash-messages");
this.addEventListeners();
}
close () {
console.log(this.getFlashMessages);
this.getFlashMessages.className = "hide";
}
addEventListeners () {
if(this.getFlashMessages)
this.getFlashMessages.addEventListener("click", this.close);
}
}
new closeFlashMessages();
My second was this:
(function (){
let getFlashMessages = document.querySelector("#flash-messages");
function close () {
console.log(getFlashMessages);
getFlashMessages.className = "hide";
}
function addEventListeners () {
getFlashMessages.addEventListener("click", function () {
close()
});
}
addEventListeners();
});
My last one is this:
(function (){
let getFlashMessages = document.getElementById("flash-messages");
getFlashMessages.addEventListener("click", close(getFlashMessages));
function close (id) {
console.log(getFlashMessages);
getFlashMessages.className = "hide";
}
});
My HTML:
<div id="flash-messages">
<div class="flash success">
<p>Recept byl přidán do nákupního seznamu.</p>
</div>
</div>
But none of them worked!! I dont understand
With the first two, I was getting undefined on my this.getFlashMessages also not sure why.
My solution is not in ES6
function Init(){
var id = document.getElementById('flash-messages');
var msg = document.querySelector('.flash');
id.addEventListener('click',function(){
msg.className = 'hide';
});
}
Init();
see demo here
I am not very much familiar with ES6.
But if I try similar code sample on a javascript it will be as given below and I hope it will be almost similar in ES6 aswell.
var getFlashMessages = document.getElementById("flash-messages");
getFlashMessages.addEventListener("click", function()
{
clicked(getFlashMessages);
});
function clicked(id){
console.log(id);
id.className = "hide";
}
Here, I am calling anonymous function, and its default argument will be event object as given in https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener.

changed.jstree event not working in jstree inside of class method

I am working on jstree checkbox plugin and I want to get the checked and unchecked state of the checkbox items. The changed.jstree event is not working in the _setEvents() method. But it is working fine when I add the event inside of _setTree() method. I need to get the event trigger in _setEvents() method.
This is the code I am using:
export default class Test {
constructor(container) {
this._tab = null;
this._container = container;
this._setEvents();
}
get tab() {
return this._tab;
}
show(data) {
this._data = data;
this._setTree();
return this;
}
_setEvents() {
const self = this;
$(document)
.on('click', '#js-image-container', () => {
$('#js-image-uploader').trigger('click');
});
$('#js-categories-container').on('changed.jstree', () => this._handleSelection());//this wont work
return this;
}
_setTree() {
$('#js-categories-container').jstree(jsonTreeGenerator.generate(this._data.categories));
$('#js-categories-container').on('changed.jstree', () => this._handleSelection()); //this will work
return this;
}
_handleSelection() {
alert(1);
}
}
Since you are adding the js-categories-container element dynamically, I believe it is not there yet at the time when you bind an event to it. So you have to delegate event handling, e.g. same way as you do for the js-image-container element. Check demo - Fiddle Demo:
$(document).on('click', '#js-image-container',
() => { $('#js-image-uploader').trigger('click'); }
);
$(document).on("click", '#js-categories-container',
() => {
// get the node if you need it
var node = $('#js-categories-container').jstree().get_node(event.target);
// do something
this._handleSelection();
}
);

jQuery toggle triggers effect instead of handler [duplicate]

$('.slideArrow').toggle(function (event) {
//some code
}, function (event) {
//some code
});
This works fine for content which are loaded on page-load.But the same function does not work for content loaded with ajax.It just does not intercept the click.
What should I do?
In an other scenario,i faced a same problem(not for toggle,for click) and sorted it this way.I dont know what to do for toggle?
$('.common-parent').on('click','.target-of-click',function(){
//some code
})
The flag method :
var flag = false;
$(document).on('click', '.slideArrow', function(event) {
if (flag) {
// do one thing
}else{
// do another thing
}
flag = !flag;
});
the data method
$(document).on('click', '.slideArrow', function(event) {
if ( $(this).data('flag') ) {
// do one thing
}else{
// do another thing
}
$(this).data('flag', !$(this).data('flag'));
});

Categories