This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 5 years ago.
I am new to Javascript programming and I'm trying to learn it by myself. I tried to make a plugin which allows element assigned moving back and forth, but it does not work. Could anyone help me and tell me what the problem with my code? Below is the code with I am trying to develop my plugin.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
Hello, world
<img src="car.png" style="width:100px; height:60px">
<p>Hello, world</p>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script>
(function( $ )
{
$.fn.showLinkLocation = function()
{
move();
function move()
{
$(this).animate({left: '500px'}, 1000).animate({left: '0px'}, 1000);
move();
};
};
}( jQuery ));
$( "a" ).showLinkLocation();
</script>
</body>
</html>
(function($) {
$.fn.showLinkLocation = function() {
this.animate({
left: '500px'
}, 1000).animate({
left: '0px'
}, 1000);
return this;
};
})(jQuery);
$("a").showLinkLocation();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Hello, world
Cause :
You got, recursive call not gonna break, infinite loop :
function move(){
...
move();
};
Explanation:
Using jQuery rather than $ ensures there are no conflicts with other JavaScript libraries. All our internal code should also refer to jQuery rather than $.
(function($) {
$.fn.showLinkLocation = function() { ... };
})(jQuery);
This function runs immediately and is passed jQuery as a parameter named $. Since $ is a local variable, we can assume that it always refers to the jQuery library rather than another library that grabbed the global $ variable first.
this refers to jQuery, so we can access jQuery's methods directly, like this.each(...
return this; return the jQuery object so other methods can be chained
I think what was wrong with your code is that, inside the inner move function, you did not have access to its outer this variable, which was the target element in this case.
So, you needed to keep outer this in a separate variable, so it's not overriden by the function in that function's context. In any case, I think Akshay Hegde's solution below is much cleaner.
Another issue is that you are calling move() repeatedly which eventually will crash the browser. You should wait for the first animation to complete, before starting it again.
(function( $ ) {
$.fn.showLinkLocation = function() {
var $this = this;
move();
function move(){
console.log("move called" + new Date().getTime() );
$this.addClass("animating").animate({left: '500px'}, 1000).animate({left: '0px'}, 1000);
//move();
};
};
}( jQuery ));
$( "a" ).showLinkLocation();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
Hello, world
<img src="car.png" style="width:100px; height:60px">
<p>Hello, world</p>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>
Related
This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 2 years ago.
Following this page, I'm finding that I can't execute an 'onclick' handler like the handler set up here:
function handler() {
console.log(5);
}
<button onclick="handler()"></button>
This is the only module I use: <script type="module" src="../js/js_test.js"></script>. It's in the header.
This is the error I get:
It works when I have this in my module:
let button = document.querySelector('button');
button.onclick = handler;
Any ideas?
P.s. I can't access variables I write on my module on the console. I thought I once could do this. Don't know if that's helpful.
you can also use export and import. exporting your functions and importing it to another file
In js_test.js do
export function handler() {
console.log(5);
}
In the html do
<html>
</head>
<script type="module" src="../js/js_test.js"></script>
<script type="module">
import {handler} from '../js/js_test.js';
document.onload = function(){
document.getElementById('myButton').addListener("click", handler);
};
</script>
</head>
<body>
<button id="myButton"></button>
</body>
</html>
EDIT per the suggestion of Aks Jacoves
An old way of doing module was
In js_test_old.js do
(function _module_x (global) {
global.myNamespace = global.myNamespace || {};
global.myNamespace.handler = _handler_;
function _handler_ () {
console.log(5);
}
})(window); // or })( (function(){return this;})() ); // this works for both Node.js and html
In the html do
<html>
</head>
<script src="../js/js_test_old.js"></script>
</head>
<body>
<button onclick="myNamespace.handler()"></button>
</body>
</html>
Be sure to add a listener if the html element has finished loading
document.onload = function(){
function handler(){
console.log(5);
}
}
This question already has an answer here:
JavaScript setTimeOut doesn't seem to work like I expect
(1 answer)
Closed 5 years ago.
I'm trying to make one div fade out after 5 seconds, and then have a new div appear with JQuery.
Here is my current code: https://pastebin.com/M7D6qMWi
<script>
$(document).ready(function(){
function hidehero(){
$("#hero").fadeOut();
};
function showmain(){
$("main").show();
};
function timeouts(){
setInterval(hidehero(), 3000);
setInterval(showmain(), 5000);
};
timeouts();
});
Unfortunately, the first div just instantly disappears and the new div instantly appears, and it isnt listening to the intervals.
If anyone knows how to fix this let me know!
Change
setInterval(hidehero(), 3000);
setInterval(showmain(), 5000);
with:
//Pass the function, not the return value of the function.
setInterval(hidehero, 3000);
setInterval(showmain, 5000);
You're calling the function instantly that's why it isnt working as expected. setInterval takes a function as its first parameter, and you're passing undefined since hidehero function doesn't return anything.
BTW you should use setTimeout and not setInterval, in your code there is no need to call hidehero every 3 seconds.
Your showmain function is also wrong, since you're missing # in $("main"). To reference an ID in jQuery use $("#main")
Here's a working demo:
$(document).ready(function() {
function hidehero() {
$("#hero").fadeOut();
};
function showmain() {
$("#main").show();
};
function timeouts() {
setTimeout(hidehero, 3000);
setTimeout(showmain, 5000);
};
timeouts();
});
<!DOCTYPE html>
<html>
<head>
<title>Sevi Home</title>
<link rel="shortcut icon" type="image/png" href="favicon.ico" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="css.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
</script>
</head>
<body>
<div id="hero">
<div class="header">SEVI<br></div>
</div>
<div id="main" style="display:none"><div class="header2">ELLO!!!!!!</div></div>
</body>
</html>
Change setInterval() for setTimeout() and it'll work.
Try this:
$(document).ready(function(){
setTimeout(function() {
$("#hero").fadeOut(function() {
$("#main").show();
});
}, 5000);
});
What am doing wrong. I try to make object but when i try to initialize i get this error in console: I try to put all in document.ready and whitout that but dont work. In both case i have some error. Am new sorry for dumb question
ReferenceError: Circle is not defined
var obj = new Circle;
JS
$(function(){
var Circle = {
init: function() {
console.log("Circle initialized");
}
};
});
HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="javascript/circle.js"></script>
<script>
$(document).ready(function(){
var obj = new Circle;
obj.init();
})
</script>
</head>
<body>
<div id="test" >TODO write content</div>
</body>
</html>
NEW UPDATE
$(function(){
window.Circle = {
init: function() {
console.log("Circle initialized");
}
};
window.Circle.init();
});
....
<head>
<script>
window.Circle().init();
</script>
</head>
You've defined your "Circle" function inside another function — the anonymous function you pass in as a a "ready" handler. Therefore, that symbol ("Circle") is private to that function, and not visible to the other code.
You can make it global like this:
window.Circle = {
// ...
};
You could also add it to the jQuery namespace (may or may not be appropriate; depends on what you're doing), or you could develop your own namespace for your application code. Or, finally, you could consider combining your jQuery "ready" code so that the "Circle" object and the code that uses it all appears in the same handler.
edit — another possibility is to move your "Circle" declaration completely out of the "ready" handler. If all you do is initialize that object, and your property values don't require any work that requires the DOM or other not-yet-available resources, you can just get rid of the $(function() { ... }) wrapper.
1) you are assigning Circle in a function context, not as a global. You can only use it there unless you expose it to global.
2) you are calling Circle as a constructor, but Circle is not a function.
This solves both issues:
var Circle = function () {};
Circle.prototype.init = function () {
console.log('Circle initialized.');
};
var obj = new Circle();
obj.init();
I think the pop window with OK string will be dislayed afetr 5s after I click the button, but the pop window dispalyed immediately after I click the button, why?
Thanks!
<html>
<head>
<title>Wake up call</title>
<script type="text/javascript">
function wakeUpCall() { // Function is defined here
setTimeout(aa("ok"), 5000);
}
function aa(bb) {
alert(bb);
}
</script>
</head>
<body bgcolor="lightblue">
<form>
<input type="button"
value="Wake me"
onclick="wakeUpCall()">
</form>
</body>
</html>
function wakeUpCall() { // Function is defined here
setTimeout(function(){ alert("ok");}, 5000);
}
You are trying to do it the wrong way.
You have to use a callback for the setTimeout:
setTimeout(function()
{
// actual code here
}, 5000);
Mike has provided in his answer - that you could use an evaluatable string:
setTimeout('/* actual code here */', 5000);
But that is strongly discouraged, use his other example - passing the callback function as a reference and invoking callback arguments.
You have to take in mind, though, that if you are going with callback arguments, see this section of MDN article. The callback arguments aren't supported in all browsers.
Personally, I'd suggest going with plain old callbacks, because that's how the setTimeout is meant to be used.
Just for your information:
The reason why your snippet isn't working for you, is, because:
setTimeout(aa('ok'), 5000);
// aa('ok') here is executed, and returns its value, so, in the end, you pass the returned value of aa inside the Timeout.
// and, nor alert alert, nor your function have a "return" statement, so they both will return always undefined.
// that translates to:
setTimeout(undefined, 5000); // and, that does nothing
What if you would do it like this:
<html>
<head>
<title>Wake up call</title>
<script type="text/javascript">
function wakeUpCall() { // Function is defined here
setTimeout('aa("ok");', 5000);
}
function aa(bb) {
alert(bb);
}
</script>
</head>
<body bgcolor="lightblue">
<form>
<input type="button"
value="Wake me"
onclick="wakeUpCall()">
</form>
</body>
</html>
Notice I have quoted the statement to execute in the setTimeout function. It those quotes confuse you, I think this is a good resource to take a look at: https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout
Another way to do it, I just learned from the resource above, is like this:
function wakeUpCall() { // Function is defined here
setTimeout(aa, 5000, "Your tekst here");
}
Use anonymous functions for this.
<html>
<head>
<title>Wake up call</title>
<script type="text/javascript">
function wakeUpCall() { // Function is defined here
setTimeout(function(){aa("ok");}, 5000);
}
function aa(bb) {
alert(bb);
}
</script>
</head>
<body bgcolor="lightblue">
<form>
<input type="button"
value="Wake me"
onclick="wakeUpCall()">
</form>
</body>
</html>
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Nested function parameters and 'this' context in Javascript
I'm currently having problems to design my JS classes as desired due to a problem using 'this' in a nested class function call. Don't know how to describe it better so here's a sample what I mean.
test.html
<!DOCTYPE html>
<html class="main" lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="test.js"></script>
<script type="text/javascript">
function doIt() {
var myTestClass = new TestClass();
}
</script>
</head>
<body>
<button onclick="doIt();">Do it!</button>
</body>
</html>
test.js
function TestClass() {
// this is working
this.alertValue('This works');
// this is not working
setTimeout(function(){this.alertValue('This does not work!')}, 1000);
}
TestClass.prototype.alertValue = function(value) {
alert('Value is: ' + value);
}
Of course this is just a simplified example to demonstrate the problem I mean.
So how could I use the 'this' identifier within the function inside the setTimeout call or how would be a better / the correct way to achieve that?
Thanks a lot for your help in advance!
Cheers
Save the value of this in a variable (self) and then you can access it within setTimeout.
function TestClass() {
this.alertValue('This works');
var self = this;
setTimeout(function() {
self.alertValue('This does not work!')
}, 1000);
}