Why do i have to enclose jQuery commands in a function [closed] - javascript

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm currently working my way through Learning jQuery by Karl Swedberg where all jQuery code samples in the book are contained in $(document).ready().
While i understand why the code has to be contained in $(document).ready(),namely so that they will be run only when the HTML document has loaded, the book does not explain why any code has to be placed inside a function.
E.g
$(document).ready(function(){
alert("The page has loaded.");
alert("2nd alert.");
});
In the example above, why does the alert have to be contained in a function() to work, and cannot an example like the one below will not work.
$(document).ready(
alert("The page has loaded.");
alert("2nd alert.");
);
I would appreciate if anyone can enlighten me.

Reads Docs, it specify a function to execute when the DOM is fully loaded.
.ready( handler )
Where, handler
Type: Function()
A function to execute after the DOM is ready.

$(document).ready accepts a callback. A callback is a javascript function. Javascript functions can be passed around just like variables. In the case above you are using an inline anonymous function, that is a function with no name.
You could rewrite your example like this:
function doStuff() {
alert("The page has loaded.");
alert("2nd alert.");
}
$(document).ready(doStuff);
You need to use a function because you cannot pass statements as parameters to a function but you can pass a function.
Note if you don't want to have to type as much there is a shorthand notation that is functionally equivalent:
$(function() {
alert("The page has loaded.");
alert("2nd alert.");
});
or without the inline function:
function doStuff() {
alert("The page has loaded.");
alert("2nd alert.");
}
$(doStuff);

$(document).ready() expects a function. Your second example is actually a syntax error, since alert("The page has loaded."); alert("2nd alert."); is not a valid parameter list.
The reason you typically have to use $(document).ready() in jQuery is because you are usually interacting with DOM nodes (which aren't actually available in the DOM yet if your script happens to be at the top of the page). An alternative is to put your script at the bottom of the page, at which point all of the DOM nodes you need are available, and there's no need for the $(document).ready() wrapper.

Related

Printing string in JavaScript is giving error [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am trying to print 2 strings. What is wrong here?
function alpha(name1, name2){
console.log(name1, name2);
}
<button onclick=alpha("Peter", "Jack")>ok</button>
Others have already told you that the issue is that the value of your onclick needs to be quoted and those quotes should not conflict with the quotes you are already using around your function arguments, but I have a different approach for you....
You really shouldn't be using inline HTML event attributes (i.e. onclick) in the first place. This is a 25+ year old technique that just won't die because it's easy to understand and most new developers just copy someone else's code and convert it to their needs. There are many reasons why this old technique should just fade away and instead, you should use the modern API for event binding, which is .addEventListener().
In your case, it's not obvious why a button would have function arguments hard-coded into it, but if that really is your use case, those should be stored as data-* attributes.
Here's your scenario, reworked into code from this century:
// Get a reference to the DOM element you need to work with
let btn = document.querySelector("button");
// Get the data-* into an array
let people = btn.dataset.people.split(",");
// Do the event binding in JavaScript, not HTML
// We'll set the click event to invoke an anonymous
// function that itself calls the real function and
// passes the proper arguments.
btn.addEventListener("click", function(){
alpha(people[0], people[1]);
});
function alpha(name1, name2){
console.log(name1, name2);
}
<!-- Notice that the data is held in a data-* attribute and
that the code to hook up the event is gone from the HTML. -->
<button data-people="Peter,Jack">ok</button>
You are wrongly defining the handler of onclick.
function alpha(name1, name2){
console.log(name1, name2);
}
<button onclick="alpha('Peter', 'Jack')">ok</button>
You are missing a pair of quotes.
<button onclick="alpha('Peter', 'Jack')">ok</button>
You need quotation marks around the function in HTML
function alpha(name1, name2){
console.log(name1, name2);
}
<button onclick="alpha('Peter', 'Jack')">ok</button>
Using Single quotes '' in the html instead of double will solve the issue. Also put quotes around the function
function alpha(name1, name2){
console.log(name1, name2);
}
<button onclick="alpha('Peter', 'Jack')">ok</button>

How can I call an object method using a function argument? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
So I asked a similar question before... I wanted to know how to argue for the css property in a document.element.style.property=value. The solution was simple, and almost made sense --but clearly I didn't understand it entirely or I'd know trying the same solution for .element doesn't work.
Here is my code:
function appendElement(handle){
element=document[handle]('div');
document.body.appendChild(element);
}
This way I could choose to create a new element or shift an existing one based on id or class or index appearance or whatever. Of course even without knowing the correct way to do this, the code I have above looks wrong to me, but it's the best I can do without some assistance.
EDIT: Test case
/* The core instructions */
element=document.createElement('div');
document.body.appendChild(element);
/* the choosy version */
function appendElement(handle){
element=document[handle]('div');
document.body.appendChild(element);
}
appendElement(createElement);
element.innerHTML="third text";
/* SHOULD move the 'text' div under the 'third text' div*/
appendElement(getElementById('first'));
<div id="first">text</div>
<div>second text</div>
Edit
In this line appendElement(getElementById('first'));you are not passing a function as you want, you are passing the result of call undefined with the param 'first', because it can't find a function in that context or a global function called getElementById (so it will be undefined), furthermore your are trying to execute undefined passing it a string... this is going to raise an error, and in the case in which function existed (i.e you pass document.getElementById('first')), then you will be passing the returned value of executing that function instead of the function.
If you want to pass a function you should pass a function, thats is appendElement(document.getElementById), without calling it with an argument, but I think you are going to need to pass a selector to that function to accomplish what you are trying to do. So
the code will be something like this:
function appendElement(handle, selector){
element=handle.call(document, selector);
document.body.appendChild(element);
}
appendElement(document.getElementById, 'first');
<div id="first">text</div>
<div>second text</div>
call allows you to execute a function as a method and specify which object will be the receptor of that calling. Here is more info
I didn't understand your need.
But, if handle is equals to 'createElement', which is a property of document, your code will run.

Lightening effect with javascript [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to use recursion in JavaScript to produce an infinite loop. In fact, I desire to give an image a come-and-go effect, endlessly.
Let's take a look at some code first :
function lightening(){
$('#pic_holder').fadeOut(250).fadeIn(250);
setTimeout('lightening', 250);
}
This function, as it's written, should
apply the fadeOut(250) and fadeIn(250) effects ;
engage the setTimeout function which in its turn must call recursively the lightening function, henceforth re-applying the [fadeOut-fadeIn effect and setTimeout] block of code.
This, you'll agree, should go ad infinitum, but it doesn't.
Here's the full test code, with HTML, as you can notice, it applies the fadeOut-fadeIn effect only once.
What am I doing wrong ?
What you really should do is this:
function lightening(){
$('#pic_holder').fadeOut(250).fadeIn(250, lightening);
}
That'll make the next cycle start when the fade-in has completed. Mixing your own timeouts with timeouts implied by jQuery animation calls is tricky and usually unnecessary. In your case, you're starting a new cycle halfway through a previous one, which really won't take effect until 250 milliseconds later.
The first argument to setTimeout can either be:
a function to be called; or
a string of JavaScript to be executed
Your function isn't being called, because you just have its name in a string. Remove the single quotes.
function lightening(){
$('#pic_holder').fadeOut(250).fadeIn(250);
setTimeout(lightening, 250);
}
See the Mozilla Documentation for proper usage.
Instead of using 2 competing timers that will either have intermittent bugs or have to be too generous, use the callback:
function lightening(){
$('#pic_holder').fadeOut(250).fadeIn(250, lightening);
}
Remove quote.
setTimeout(lightening, 250);

Javascript closures and scope issues [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I can't wrap my head around javascript closures. I want 4 random numbers, but only get the the last one replicated 4 times.
Javascript
$(function() {
function setNewNumber(element) {
return function (newNumber) {
element.text(newNumber);
}
}
$('.number').each(function() {
$.get('http://www.random.org/integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new',
setNewNumber($(this))
);
});
});
HTML
<div class="number"></div>
<div class="number"></div>
<div class="number"></div>
<div class="number"></div>
A working plunker example
Any hints?
The get request is being cached.
http://jsfiddle.net/hCEbd/1/
(That is to say your understanding of closures is correct and the code is working correctly).
From comments, because this is relevant:
You can request multiple numbers from random.org at the same timer per their API. Instead of using four requests, use num=' + $(".number").length and then do a little parsing
It's a little confusing what you're trying to achieve with your top functions. If all you want to do is set the new random number to the element, you don't need either of them.
Use ajax to specify a few parameters to your request. In particular, you want to stop caching of your request. You can also supply a context to reference your .number element.
$('.number').each(function() {
$.ajax({
type: "GET",
url: 'http://www.random.org/integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new',
context: this,
success: function(data) {
$(this).text(data);
},
cache: false
});
});
This solution fiddle here.
Works: http://plnkr.co/edit/XTOI20kGbFbzdtDaqpLZ
Your request is being cached. By the way, getting data in cycle - it's not a good idea.
Any jquery ajax request, like $.get, changes the scope. If you want to reuse your setNewWord function it needs to be either be globally scoped or scoped in the result of the get.
Take a look at the jsfiddle.
http://jsfiddle.net/justengland/hJnXb/2/
function setNewWord(element) {
$('#output').append(element + '<br>');
}
$(function () {
$(numbers).each(function () {
var url = 'http://www.random.org/integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new';
$.get(url, setNewWord);
});
});

Which strategy makes more sense in this jQuery plugin? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm making a jQuery plugin that displays alerts on the page. The plugin itself inserts the alert markup into the DOM. Since the jQuery way is to make everything return this to maintain chaining, I've run into an interesting issue I'd like feedback on. I'm trying to decide between the following two options.
Option One:
$("#content").alert('prepend', {type:'error', message:'This is an error'})
This looks pretty simple. An alert is prepended to the beginning of the #content DOM element. The problem is that it's unclear what is returned. It would make sense to return the alert element that was just created, but that kind of goes against the jQuery way.
Option Two:
$("<div>").alert({type:'error', message:'This is an error'}).prependTo("#content")
This way seems less clear and less intuitive, but it's more inline with the jQuery way of doing things, and it's clear what element is going to be returned.
So which options would you choose? My concern is that most users may not know that you can do $('<div>') to create a new element. On the other hand, I don't know of any well-known projects whose jQuery plugin methods return elements other than the elements they're invoked on, but perhaps there are. Thoughts?
I would just put it in the jQuery namespace (instead of on its prototype):
$.alert({type:'error', message:'This is an error'}).prependTo("#content");
In addition, you might consider asking for a selector/DOM node/jQuery object, instead of having the user prepend it themselves:
$.alert({
parent: '#content', // or $('#content') or document.getElementById('content')
type: 'error',
message: 'This is an error'
});
If your alert system is meant to be a popup-like or modal-like system, the user shouldn't have to specify a container. However, you can allow him to pass a container to insert your alertbox in:
$.alert({
type: 'error',
message: 'This is an error',
container: $(...) // Optional
});
It would return your plugin instance, or the alert container.
No, jQuery does not always return this. Chainability means only that you should return the instance itself if there's no result of your method.
For example, the clone() returns a new jQuery instance too; so there's nothing wrong with it. If you say "it's unclear", just document it, or rename the method to e.g. "$.fn.getAlert".
Yet, you must choose the signature of your method. The first option is like having a mandatory parameter for the container. If you like to make it optional, you might make the alert system a static method: $.createAlert(...) with an optional parameter.

Categories

Resources