how to destroy a function in another function javascript? - javascript

Function:
function abc()
{
$('#table_id tr td').removeClass('highlight');
$(this).addClass('highlight');
tableText($table_label,$table_id);
}
abc();
function refresh()
{
abc().hide; // Need help at this.
}
<button class="refresh" onclick="refresh()">Refresh</button>
I'm trying to remove function/stop running abc() function, when refresh button was clicked.

Try this code, if abc is in the global scope:
window.abc = function() {
return false;
}
or you could do: window.abc = undefined when it's in the global scope.
when it's a method: delete obj.abc

You can pass param in your function and check condition like below.
function abc(arg) {
if (arg) {
$('#table_id tr td').removeClass('highlight');
$(this).addClass('highlight');
tableText($table_label, $table_id);
} else {
//Do what ever you want if needed
}
}
abc(true);
function refresh() {
abc(false)
}

Put all the code you only want to run once at the start inside window.onload
window.onload = function() {
$('#table_id tr td').removeClass('highlight');
$(this).addClass('highlight');
tableText($table_label,$table_id);
}

Wrap the function inside an object to delete it. You can use the window object or create a new one. Example:
const functions = new Object;
functions.abc = () => { /* do something */ };
functions.abc();
const refresh = () => {
if ('abc' in functions){ functions.abc(); delete functions.abc; }
else { /* will do nothing */ }
};
Solved :-)

Related

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.

Consolidate function with wildcard?

I want to consolidate the following function into something more eloquent.
Basically I want to get element by id like "title#" and push "#" into the function so that if you click on title#x you will ReverseDisplay link#xcontent.
Appreciate any advice thank you.
document.getElementById("title1").onclick = function() {myFunction()};
function myFunction() {
ReverseDisplay('link1content');
}
document.getElementById("title2").onclick = function() {myFunction1()};
function myFunction1() {
ReverseDisplay('link2content');
}
document.getElementById("title3").onclick = function() {myFunction2()};
function myFunction2() {
ReverseDisplay('link3content');
}
document.getElementById("title4").onclick = function() {myFunction3()};
function myFunction3() {
ReverseDisplay('link4content');
}
document.getElementById("title5").onclick = function() {myFunction4()};
function myFunction4() {
ReverseDisplay('link5content');
}
document.getElementById("title6").onclick = function() {myFunction5()};
function myFunction5() {
ReverseDisplay('link6content');
}
document.getElementById("title7").onclick = function() {myFunction6()};
function myFunction6() {
ReverseDisplay('link7content');
}
document.getElementById("title8").onclick = function() {myFunction7()};
function myFunction7() {
ReverseDisplay('link8content');
}
You can use document.querySelectorAll():
const ReverseDisplay = x => console.log(x)
Array.from(document.querySelectorAll('[id^="title"]'))
.forEach(el => el.addEventListener('click', () =>
ReverseDisplay(`link${el.id.split('title').join('')}content`)))
<div id="title1">title1</div>
<div id="title2">title2</div>
<div id="title3">title3</div>
document.querySelectorAll() returns a NodeList, so we have to use Array.from() to be able to use array methods like forEach. Then we add a click event listener to each element using addEventListener() (see addEventListener vs onclick). Using split('title').join('') we remove the 'title' part from the ID and leave only the number. If you're wondering what are these ` and =>, see template literals and arrow functions.

Calling Javascript Functions by name

If I have an element on the page like this ...
<span data-function="DoSomething">Click</span>
... and i put this in my page header ...
$(document).ready(function()
{
$('[data-function]').each(function()
{
var fName = $(this).attr('data-function');
$(this).click(fName);
});
});
... what goes in place of the comment produce the desired effect of executing the function called "DoSomething".
Note:
I no the code above wont work, my question is how to make this work (translate 'DoSomething' in to DoSomething();)
Any ideas guys?
The functions should be available. Try putting them in an Object, like this:
$(document).ready(function()
{
var fns = {
DoSomething: function() {/* ... */},
DoAnotherthing: function() {/* ... */}
};
$('[data-function]').each(function()
{
var fName = $(this).attr('data-function');
$(this).click(fns[fName]);
});
});
Here's a jsfiddle, demonstrating a way to keep everything local to one namespace and assigning handlers based on the data attribute of elements.
Try calling function with window object -
$(document).ready(function() {
$('[data-function]').each(function() {
var fName = $(this).attr('data-function');
if (typeof (window[fName]) === "function") {
$(this).click(window[fName]);
}
});
}
You can use something like
$(this).click(window[fName]);
Where window would be replaced by the appropriate expression if the function DoSomething is not defined in the global scope.
Maybe a little bit clean way:
http://jsfiddle.net/whsPG/
var myfuncs = {
alert : function() {
alert("An Alert");
},
changeName: function(obj) {
$(obj).text('Other Text');
}
};
$('[data-function]').on('click', function()
{
value = $(this).data('function');
if (myfuncs.hasOwnProperty(value)) {
myfuncs[value](this);
}
});
​

Self invoking function that can be called as well

The following code works, but I'd like to use the self-invoking function syntax when declaring it instead of calling it explicitly on the last line:
var ShowMe = function() {
if ($('input:checkbox:checked').length) {
$('#Save').fadeIn('slow');
} else {
$('#Save').hide();
}
};
$('input:checkbox').on('click',ShowMe);
ShowMe();
You can't declare the var inside of an expression, but you can put its definition in one:
var ShowMe; (ShowMe = function() {
if ($('input:checkbox:checked').length) {
$('#Save').fadeIn('slow');
} else {
$('#Save').hide();
}
})();
$('input:checkbox').on('click',ShowMe);
Try this instead:
var ShowMe = function() {
if ($(this).length) { // `this` is the input that was clicked
$('#Save').fadeIn('slow');
} else {
$('#Save').hide();
}
};
$('input:checkbox').on('click', ShowMe).trigger('click');
Update based on comments below:
$('#Save').hide();
$('input:checkbox').on('click', function() {
if(this.checked) { //check if this is checked
$('#Save').show('slow');
}
else if(!($('input[type="checkbox"]:checked').length)) {
//check to see if anything else was checked
$('#Save').hide();
}
});

javascript - recursive function & setTimeout

I am trying to write a javascript function that when called performs function DoSomething() once,
but can be triggered to perform the function repeatedly until triggered to stop.
I am using setTimeout() function. I am not sure if this is best method from performance and memory point of view.
Also I would like to avoid global variable if possible
<!DOCTYPE html>
<html>
<script src="jquery.js"></script>
<script>
var globalCheckInventory = false;
$(document).ready(function(){
// start checking inventory
globalCheckInventory = true;
myTimerFunction();
});
// check inventory at regular intervals, until condition is met in DoSomething
function myTimerFunction(){
DoSomething();
if (globalCheckInventory == true)
{
setTimeout(myTimerFunction, 5000);
}
}
// when condition is met stop checking inventory
function DoSomething() {
alert("got here 1 ");
var condition = 1;
var state = 2 ;
if (condition == state)
{
globalCheckInventory = false;
}
}
</script>
This is probably the easier way to do what you're describing:
$(function () {
var myChecker = setInterval(function () {
if (breakCondition) {
clearInterval(myChecker);
} else {
doSomething();
}
}, 500);
});
Another way to do it would be the store the timer ID and use setInterval and clearInterval
var timer = setInterval(DoSomething);
function DoSomething() {
if (condition)
clearInterval(timer);
}
I see nothing wrong with your implementation other than the pollution of the global namespace. You can use a closure (self-executing function) to limit the scope of your variables like this:
(function(){
var checkInventory = false, inventoryTimer;
function myTimerFunction() { /* ... */ }
function doSomething() { /* ... */ }
$(document).ready(function(){
checkInventory = true;
/* save handle to timer so you can cancel or reset the timer if necessary */
inventoryTimer = setTimeout(myTimerFunction, 5000);
});
})();
Encapsulate it:
function caller(delegate, persist){
delegate();
if(persist){
var timer = setInterval(delegate, 300);
return {
kill: function(){
clearInterval(timer);
}
}
}
}
var foo = function(){
console.log('foo');
}
var _caller = caller(foo, true);
//to stop: _caller.kill()

Categories