Reputation: 77
Why does the first block using an anonymous function work differently from the second using a named function? The first block changes between "Hello" and "Goodbye" but the second doesn't.
1st — Using anonymous function:
function sayGoodbye() {
$("#title").html("Goodbye");
$("#title").click(function () {
$("#title").html("Hello");
$("#title").off("click");
});
};
2nd — Using named function:
function sayGoodbye() {
console.log("goodbye");
$("#title").html("Goodbye");
$("#title").click(sayHello());
};
function sayHello() {
console.log("hello");
$("#title").html("Hello");
$("#title").off("click");
}
HTML:
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<h1 id="title" onclick="sayGoodbye();"> Hello </h1>
</body>
Upvotes: 2
Views: 78
Reputation: 54676
A couple of improvements to the code.
Read Decoupling Your HTML, CSS, and JavaScript.
Html:
<body>
<h1 class="js-say is-hello">
<span class="say say-hello">Hello</span>
<span class="say say-goodbye">Goodbye</span>
</h1>
</body>
CSS:
// any class with say should be hidden
.say {
display: none; }
// over-ride previous, if we're in an element of is-hello show say-hello
.is-hello .say.say-hello{
display: inline; }
// over-ride previous, if we're in an element of is-goodbye show say-goodbye
.is-goodbye .say.say-hello{
display: inline; }
jquery
$(".js-say").on('click', function () {
var $this = $(this);
$this.toggleClass('is-hello');
$this.toggleClass('is-goodbye');
});
.js-say
- is now the trigger for your jquery. It is decoupled from any CSS that may run on the element. I prefixed it with js-
meaning this should never have a CSS rule and should only be used for javascript events.
is-hello
& is-goodbye
- describes the state of the h1
element. They help CSS to show or hide elements within the h1
. I removed the HTML from javascript (decoupled) and I rarely use javascript in this way to update HTML because it's really hard to figure out who and from where the HTML is updated.
My personal opinion is not to use .click()
and just stick with the newer and more extensible .on()
. toggleClass()
does what it sounds like, if the class exists, remove it, if it doesn't, add it.
Upvotes: 1
Reputation: 206689
$("#title").click(sayHello()); use:
$("#title").on("click", sayHello);
(or... $("#title").click(sayHello);
)
you should assign a sayHello
, not execute a sayHello()
function sayGoodbye(){
console.log("goodbye");
$("#title").html("Goodbye");
$("#title").click(sayHello);
};
function sayHello() {
console.log("hello");
$("#title").html("Hello");
$("#title").off("click");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="title" onclick="sayGoodbye();"> Hello </h1>
Here's another nice reading about toggling two states or two functions:
https://stackoverflow.com/a/21520499/383904
Upvotes: 4
Reputation: 12672
When you put in sayHello(), that uses the result of executing sayHello. Instead, what you should do is pass sayHello, with no parenthesis, which represents the function itself
Upvotes: 0