Anonymous function warning - javascript

I have a problem on my code and I don't know how to fix it.
Where I write "IMPORTANT HERE" the console tell me the function(e) is anonymous. How can I resolve my problem?
(function() {
var theForm = document.getElementById('theForm'),
inputs = document.querySelectorAll('input[type=text]'),
inputsLength = inputs.length;
for (var i = 0; i < inputsLength; i++) {
inputs[i].addEventListener('keyup', function(e) {
check[e.target.id](e.target.id);
});
}
theForm.addEventListener('submit', function(e) { //IMPORTANT HERE
var result = true;
for (var i in check) {
result = check[i](i) && result;
}
if (result) {
alert('Le formulaire est bien rempli.');
}
e.preventDefault();
});
theForm.addEventListener('reset', function() {
for (var i = 0; i < inputsLength; i++) {
inputs[i].className = '';
}
deactivateTooltips();
});
})();

Related

How to set closure to capsule global variable

I have following functions,in which I can set prompt when someone leave page while inputting some values.
My consern is how to encapsule checkFlag. in this case, checkFlag is treated as global variables.
So that it is somewhat inconvenient.
let checkFlag = false;
const onBeforeunloadHandler = function(e) {
var msg = '';
e.returnValue = msg;
};
const formAlert = function() {
if(!checkFlag) {
window.addEventListener('beforeunload', onBeforeunloadHandler);
for(var i = 0; i < checkValue.length; i++) {
checkValue[i].removeEventListener('input', formAlert);
checkValue[i].removeEventListener('change', formAlert);
}
checkFlag = true;
}
};
(() => {
let checkValue = document.querySelectorAll( "input[form='test'], textarea[form='test']");
let submitBtn = document.querySelector('button[type="button"]');
for(var i = 0; i < checkValue.length; i++) {
checkValue[i].addEventListener('input', formAlert);
checkValue[i].addEventListener('change', formAlert);
}
submitBtn.addEventListener('click', function() {
window.removeEventListener('beforeunload', onBeforeunloadHandler);
});
})();
If someone has opinion, will you please let me know.
Thanks
There's no need for anything in the outer scope. You can put it all into the IIFE.
(() => {
let checkFlag = false;
const onBeforeunloadHandler = function(e) {
var msg = '';
e.returnValue = msg;
};
const formAlert = function() {
if(!checkFlag) {
window.addEventListener('beforeunload', onBeforeunloadHandler);
for(var i = 0; i < checkValue.length; i++) {
checkValue[i].removeEventListener('input', formAlert);
checkValue[i].removeEventListener('change', formAlert);
}
checkFlag = true;
}
};
let checkValue = document.querySelectorAll( "input[form='test'], textarea[form='test']");
let submitBtn = document.querySelector('button[type="button"]');
for(var i = 0; i < checkValue.length; i++) {
checkValue[i].addEventListener('input', formAlert);
checkValue[i].addEventListener('change', formAlert);
}
submitBtn.addEventListener('click', function() {
window.removeEventListener('beforeunload', onBeforeunloadHandler);
});
})();
(() => {
let checkFlag = false;
const onBeforeunloadHandler = function(e) {
var msg = '';
e.returnValue = msg;
};
const formAlert = function() {
if(!checkFlag) {
window.addEventListener('beforeunload', onBeforeunloadHandler);
for(var i = 0; i < checkValue.length; i++) {
checkValue[i].removeEventListener('input', formAlert);
checkValue[i].removeEventListener('change', formAlert);
}
checkFlag = true;
}
};
let checkValue = document.querySelectorAll( "input[form='test'], textarea[form='test']");
let submitBtn = document.querySelector('button[type="button"]');
for(var i = 0; i < checkValue.length; i++) {
checkValue[i].addEventListener('input', formAlert);
checkValue[i].addEventListener('change', formAlert);
}
submitBtn.addEventListener('click', function() {
window.removeEventListener('beforeunload', onBeforeunloadHandler);
});
})();

Show all tabs content vanilla js

How can I change this javascript code, that when I click on "Green" I want the content from all tabs to be displayed? https://codepen.io/wangel13/pen/OXBrRp
'use strict';
function Tabs() {
var bindAll = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for(var i = 0; i < menuElements.length ; i++) {
menuElements[i].addEventListener('click', change, false);
}
}
var clear = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for(var i = 0; i < menuElements.length ; i++) {
menuElements[i].classList.remove('active');
var id = menuElements[i].getAttribute('data-tab');
document.getElementById(id).classList.remove('active');
}
}
var change = function(e) {
clear();
e.target.classList.add('active');
var id = e.currentTarget.getAttribute('data-tab');
document.getElementById(id).classList.add('active');
}
bindAll();
}
var connectTabs = new Tabs();
Take a look at this:
'use strict';
function Tabs() {
var bindAll = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for(var i = 0; i < menuElements.length ; i++) {
menuElements[i].addEventListener('click', change, false);
}
}
var clear = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for(var i = 0; i < menuElements.length ; i++) {
menuElements[i].classList.remove('active');
var id = menuElements[i].getAttribute('data-tab');
document.getElementById(id).classList.remove('active');
}
}
function makeAllActive() {
var tabs = document.querySelectorAll('.b-tab');
Array.from(tabs).map(item => {
item.classList.add('active');
});
}
var change = function(e) {
clear();
e.target.classList.add('active');
var id = e.currentTarget.getAttribute('data-tab');
if(id === "green") {
makeAllActive();
return;
}
document.getElementById(id).classList.add('active');
}
bindAll();
}
var connectTabs = new Tabs();

How can i pass javascript addListener function value to change function inside

I have addListener function and change function is there. How can I pass addListener result to change function inside using javascript
$(document).ready(function() {
// find pincode
var input = document.getElementById('location_input');
var options = {
types: ['address'],
componentRestrictions: {
country: 'in'
}
};
autocomplete = new google.maps.places.Autocomplete(input, options);
var pincode;
google.maps.event.addListener(autocomplete, 'place_changed', function fun1() {
var place = autocomplete.getPlace();
for (var i = 0; i < place.address_components.length; i++) {
for (var j = 0; j < place.address_components[i].types.length; j++) {
if (place.address_components[i].types[j] === "postal_code") {
pincode = place.address_components[i].long_name;
fun2(pincode);
//alert(pincode);
} //return pincode;
}
}
});
$('input[type="checkbox"],#location_input').change(function fun2(val) {
var ids = ['filter_AFFILIATION_1', 'filter_AFFILIATION_2', 'filter_AFFILIATION_3', 'filter_AFFILIATION_4'];
var data = {};
for (var i = 0; i < ids.length; i++) {
if (document.getElementById(ids[i]).checked === true) {
data['request' + i] = $('#' + ids[i]).val();
}
}
var pincode = val;
alert(pincode);
console.log(pincode);
});
});
Here fun1 and fun2 two functions. How can i pass fun1 pincode value to fun2 inside?
You already have defined pincode in global scope.
Just use it.
Here function fun2(val) val is Event object passed to event callback.
And you dont have to use named functions, anon funcs will work as event callbacks.
$(document).ready(function () {
// find pincode
var input = document.getElementById('location_input');
var options = {
types: ['address'],
componentRestrictions: {
country: 'in'
}
};
autocomplete = new google.maps.places.Autocomplete(input, options);
var pincode;
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
for (var i = 0; i < place.address_components.length; i++) {
for (var j = 0; j < place.address_components[i].types.length; j++) {
if (place.address_components[i].types[j] === "postal_code") {
pincode = place.address_components[i].long_name;
} //return pincode;
}
}
});
$('input[type="checkbox"]').change(function (event) {
var ids = ['filter_AFFILIATION_1', 'filter_AFFILIATION_2', 'filter_AFFILIATION_3', 'filter_AFFILIATION_4'];
var data = {};
for (var i = 0; i < ids.length; i++) {
if (document.getElementById(ids[i]).checked === true) {
data['request' + i] = $('#' + ids[i]).val();
}
}
alert(pincode);
console.log(pincode);
});
});

JavaScript: How to set a parent object as a parameter within an addEventListener function?

how can I set the object (which is part of the buttons array) as a parameter within the addEventListener function? buttons[i] is not working..
Here is a part of the code:
var buttonNames = ["canteen","locations","floorplan","guestbook","pictures"];
var buttonDivNames = ["btn1","btn2","btn3","btn4","btn5"];
var buttons = [];
window.onload = function() {
for(var i = 0; i<buttonNames.length; i++) {
var obj = new Object();
obj.targetLink = buttonNames[i] + ".html";
obj.defaultImage = "img/buttons/"+buttonNames[i]+"_default.jpg";
obj.hoverImage = "img/buttons/"+buttonNames[i]+"_hover.jpg";
obj.div = document.getElementById(buttonDivNames[i]);
obj.divPicture = obj.div.getElementsByClassName("thumbnailPicture")[0];
obj.divLink = obj.div.getElementsByClassName("thumbnailLink")[0];
buttons.push(obj);
}
for(var i = 0; i<buttons.length; i++) {
buttons[i].divPicture.addEventListener("mouseover",function() { anotherFunction(buttons[i]) },false)
}
}
function anotherFunction(arg) {
console.log(arg.targetLink);
}
Thanks guys, this way it works:
for(var i = 0; i<buttons.length; i++) {
initButton(buttons[i]);
}
}
function initButton(arg) {
arg.divPicture.addEventListener("mouseover",function() {anotherFunction(arg);},false)
}
function anotherFunction(arg) {
console.log(arg.targetLink);
}
As pointed out in the comment section, you could use an IIFE to create a new scope, that holds the value of the current i:
for(var i = 0; i<buttons.length; i++) {
(function (i) {
buttons[i].divPicture.addEventListener("mouseover",function() { anotherFunction(buttons[i]) },false)
}(i));
}
or, even better, create a seperate function that handles the adding of the eventlistener:
function addEventlistenerToButton(button) {
button.divPicture.addEventListener("mouseover",function() { anotherFunction(button) },false)
}
// ....
for(var i = 0; i<buttons.length; i++) {
addEventlistenerToButton(buttons[i]);
}
In addition to that, you could also omit sending the button to the eventlistener completely and get the button from the event object directly:
for(var i = 0; i<buttons.length; i++) {
buttons[i].divPicture.addEventListener("mouseover", anotherFunction, false);
}
function anotherFunction(ev) {
ev = ev || window.event;
var src = ev.target || ev.srcElement;
console.log(src.parentNode);
}

JavaScript continue label scope

Map.prototype.updateMap = function (vehicles) {
nextVehicle:
for (var i = 0; i < vehicles.length; i++) {
for (var j = 0; j < this.oldVehicles.length; j++) {
var vehicle = vehicles[i];
var oldVehicle = this.oldVehicles[j];
if (vehicle.registration == oldVehicle.registration) {
oldVehicle.getPosition(function(latLng) {
if (vehicle.latitude != oldVehicle.lat) {
var newPos = new plugin.google.maps.LatLng(vehicle.latitude, vehicle.longitude);
oldVehicle.setPosition(newPos);
}
continue nextVehicle;
});
}
}
}
};
The code above does not work. I have a feeling this is to do with scope, I can't reach the nextVehicle label from inside the oldVehicle.getPosition method. How can I get around this?
Separate the matching logic from the update logic.
Map.prototype.updateMap = function (vehicles) {
// Only need to look up array lengths once
var vehiclesLength = vehicles.length,
oldVehiclesLength = this.oldVehicles.length;
for (var i = 0; i < vehiclesLength; i++) {
var vehicle = vehicles[i];
var oldVehicle = null;
// Find oldVehicle
for (var j = 0; j < oldVehiclesLength; j++) {
if (vehicle.registration == oldVehicle[j].registration) {
oldVehicle = oldVehicles[j];
break;
}
}
// Check for update if found
if (oldVehicle){
// Create closure for async callbacks
(function(oldV, lat,lng){
oldV.getPosition(function(latLng) {
if (lat != oldV.lat) {
var newPos = new plugin.google.maps.LatLng(lat,lng);
oldV.setPosition(newPos);
}
});
})(oldVehicle, vehicle.latitude, vehicle.longitude);
}
}
};
Just move the continue nextVehicle; line from inside the callback to immediately following the call to oldVehicle.getPosition(...):
Map.prototype.updateMap = function (vehicles) {
nextVehicle:
for (var i = 0; i < vehicles.length; i++) {
for (var j = 0; j < this.oldVehicles.length; j++) {
var vehicle = vehicles[i];
var oldVehicle = this.oldVehicles[j];
if (vehicle.registration == oldVehicle.registration) {
oldVehicle.getPosition(function(latLng) {
if (vehicle.latitude != oldVehicle.lat) {
var newPos = new plugin.google.maps.LatLng(vehicle.latitude, vehicle.longitude);
oldVehicle.setPosition(newPos);
}
});
continue nextVehicle;
}
}
}
};
This assumes the call to getPosition is a synchronous operation.
Edit:
Now if getPosition is asynchronous, you will need to use an asynchronous loop:
Something along this line might do the trick:
Map.prototype.updateMap = function (vehicles) {
var i = 0, j = -1, self = this;
var updatePosition = function() {
j++;
if (j == self.oldVehicles.length) {
j = 0;
i++;
}
if (i === vehicles.length) {
return; // We're done
}
var vehicle = vehicles[i];
var oldVehicle = self.oldVehicles[j];
if (vehicle.registration !== oldVehicle.registration) {
updatePosition();
}
else {
oldVehicle.getPosition(function(latLng) {
if (vehicle.latitude != oldVehicle.lat) {
var newPos = new plugin.google.maps.LatLng(vehicle.latitude, vehicle.longitude);
oldVehicle.setPosition(newPos);
updatePosition();
}
});
}
};
updatePosition();
};

Categories