This is more of a jquery question than an html5 question, but a good example non-the-less.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
context = $("#mainCanvas")[0].getContext("2d");
alert(context);
context.fillStyle = "rgb(200,0,0)";
context.fillRect (10, 10, 55, 50);
context.fillStyle = "rgba(0, 0, 200, 0.5)";
context.fillRect (30, 30, 55, 50);
});
</script>
</head>
<body>
<canvas id="mainCanvas" width="800" height="600">
</canvas>
</body>
</html>
In order to call the "getContext" function on the canvas object, I have to index into the jquery object like so:
$("#mainCanvas")[0].getContext("2d")
Needing to index into the object is clunky and not intuitive. My question is, is there not a way for jquery to infer that a "missing" function on the jquery object would be contained within the wrapped object automatically? Is there some jquery syntax trick that I am missing?
Thanks.
There is no way to override a call to a missing Javascript method that I am aware of. It's a shame too, since I could really use something like that for an issue I've been working on lately. The best you can do is some sort of function wrapper, like so:
callFunction(obj, "methodName", [args], function() { /*fallback*/ });
But that's not terribly pretty and the performance will be less-than-good. shrug
In your case, though, is this really all that bad? You're only going to be making the one call and then caching off the graphics context for all the rest of your calls. If the index syntax is really all that offensive to you, going jQuery-less for this call is also a cleaner option:
var ctx = document.getElementById("mainCanvas").getContext("2d");
That's also going to be a smidge faster, if you care about such things. Really, jQuery provides pretty much nothing when it comes to canvas manipulation.
Related
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 5 years ago.
I started learning javascript after coding in java and c++ and I am trying to draw a rectangle. I can get a normal rectangle to draw If i just code normally in a script in the body but I wanna make my file look neat and have a function incase I need to call more rectangles in my program. I have googled around but I still can't figure out how to do this.
i have tried putting the function in the head section and my js file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PacMan</title>
<script scr="pac.js"></script>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//function drawRect(ctx, startX, startY, width, height, color){
//ctx.beginPath();
// ctx.rect(startX,startY,width,height);
// ctx.fillStyle = color;
// ctx.closePath();
// }
</script>
</head>
<body>
<canvas id="canvas" width="1000" height="720"></canvas>
<script>
drawRect(ctx,10,10,10,10, "#FF0000");
// this works but i can not get the function to work
//var canvas = document.getElementById("canvas");
//var ctx = canvas.getContext("2d");
//ctx.beginPath();
// ctx.rect(900, 10, 50, 50);
// ctx.fillStyle = "#FF0000";
//ctx.fill();
// ctx.closePath();
</script>
</body>
</html>
here is the .js file i created to try to keep my functions in a nice neat order so they do not clutter my files
function drawRect(ctx,h1,h2,w1,w2, color){
//i tired at one point putting this into function
//var canvas = document.getElementById("myCanvas");
// var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.rect(20, 40, 50, 50);
ctx.fillStyle = color;
ctx.fill();
ctx.closePath();
}
If I understood you correctly, you want to create a function that draws something and possibly be able to reuse that in other files?
Here's a working example to simulate a working function https://jsbin.com/puneseyuca/edit?html,js,output. You can also inspect the output area and check the DOM semantics.
There are a couple of things you should follow to make it work properly.
Put <script> just before </body>
<body>
<!-- DOM -->
// ...
<!-- Scripts -->
<script src="./path-to-your-js-file.js"></script>
</body>
Mostly you'll want to put your <script> files just before the ending body tag. Also, since you are not using any frameworks it would be good to be completely sure that the DOM is loaded, hence you could add this code:
document.addEventListener("DOMContentLoaded", function(event) {
// "DOM fully loaded and parsed"
// Insert your code here
});
This is important for the JS to be able to select elements from the DOM, otherwise they can be undefined.
Create a global variable, typically window.anything
⚠️ This should be avoided to avoid unexpected mutations and hence bugs
I do not endorse this approach, but that's how some libraries work by namespacing to the global window object. Otherwise, the variables set in 1 file are scoped to it i.e. cannot be accessed from outside.
So to do so you would declare a function and then save it to the global object i.e.
Inside e.g. duck.js
window.drawDuck = drawDuck
N.B. Be sure to check the order of your javascript files. A file declaring a global variable should come before the ones using it.
All said and done, I believe you can do what you intend to without global variables.
Hope I answered your question.
Happy Coding!
I don't do a whole lot of JavaScript, so I'm afraid this might be a really stupid question, but I've been googling around a fair lot, and while I've found quite a bit about memory leaks with jQuery, nothing seems to match my situation.
Basically, I have a page where I'm continually replacing content with newly downloaded content. To do this, I'm using jQuery's replaceWith function, passing the downloaded HTML fragment as a string. The whole page is a bit complex and takes some time to leak significant amounts of memory, but I've reproduced the memory leak with this simple HTML snippet:
<html>
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
var sequence = 1;
function update() {
$("#test").empty().replaceWith('<p id="test">Test ' + sequence++ + '</p>').remove();
setTimeout(update, 1);
}
$(document).ready(update);
</script>
</head>
<body>
<p id="test">Test</p>
</body>
</html>
Viewing this page in Chromium seems to continually eat more and more memory, and I can't seem to figure out why. The .empty() and .remove() calls on the replaceWith() line weren't there originally, but I threw them in since they were commonly suggested as fixes to DOM replacement memory leaks. Seemingly to no effect, however.
I'm pretty sure your memory leak has something to do with the recursive nature of your setTimeout(...) function.
Try this instead:
var sequence = 1;
function update() {
$("#test").empty().replaceWith('<p id="test">Test ' + sequence++ + '</p>').remove();
var timer = setTimeout(function() {
clearTimeout(timer);
update();
}, 1);
}
$(document).ready(update);
how to run this code in jsFiddle?
original code from Adam Khoury's site at http://www.developphp.com/view.php?tid=1262
I've experimented and am able to get the button to show and the canvas outline but can not get the object to animate from left to right when the button is clicked.
Here is my attempt to get it to run in jsFiddle at...
http://jsfiddle.net/Tn8xC/
function draw(x,y){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.save();
ctx.clearRect(0,0,550,400);
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect (x, y, 50, 50);
ctx.restore();
x += 1;
var loopTimer = setTimeout('draw('+x+','+y+')',30);
}
Thanks for any help.
JSFiddle's default settings have JavaScript run onLoad, or after the HTML loads.
This works well for most cases, except for when you use an on* attribute to execute JS inline, because the JS hasn't loaded, so you can't access its variables and methods.
You need to change onLoadto No wrap - in <head> in the left sidebar at the top: this places your JS in <script> tags in the head. The head loads before everything else (whatever you put in the HTML area), so when you use the onclick attribute to reference your draw() function, it has already been defined.
You can also use No wrap - in <body> because the JS will still be placed before the rest of your HTML, but placing it in the head should serve you well in most cases.
Had you checked the console, you would have seen ReferenceError: Can't find variable: draw, which would have told you that your JS hadn't loaded before you tried to access draw().
Demo
I'm following this tutorial to learn HTML5 game development using javascript and jQuery. However, I've already come across a problem. When I run the HTML page that my js file is referenced from, nothing loads, and is just a blank screen. Here is the code for both files. Note that I haven't gotten very far in the tutorial.
index.html
<HTML>
<head>
</head>
<body>
<p>HTML5 and jQuery Tests</p>
<script type ="text/javascript" src="test.js"></script>
</body>
</HTML>
test.js
var CANVAS_WIDTH = 480;
var CANVAS_HEIGHT = 320;
var canvasElement = $("<canvas width='" + CANVAS_WIDTH +"' height='" + CANVAS_HEIGHT + "'></canvas>");
var canvas = canvasElement.get(0).getContext("2d");
canvasElement.appendTo('body');
var FPS = 30;
setInterval(function() {
update();
draw();
}, 1000/FPS);
function draw() {
canvas.fillStyle = "#000";
canvas.fillText("hello.", 50, 50);
}
Any help would be greatly appreciated! Also, am I allowed to ask questions about this code in this forum, on the same thread, or do I have to stat another?
Thanks!
~Carpetfizz
You don't have an update function to call. When the setInterval fires (which is ~32ms after the script loads), you're getting an error.
You need to add jQuery.
It's a library that was written to make working with HTML easier.
It needs to exist above where test.js does.
You can either download your own copy of it, or link to a copy elsewhere on the net - both will work fine.
$ is used by jQuery as a function to intelligently grab different kinds of items: HTML, JS, etc, and return JS objects with helpful functions for working with whatever you asked for.
Anyway, the update would still have caused an error, it was just second in line, behind the missing script.
It's been a while since I've done web programming and I'm trying to start again. However, I cannot seem to get JQuery to work.
In my javascript file I have this code:
$(document).ready(function() {
$('#canvas').mousedown(function(e){
alert("I am an alert box!");
});
});
However, nothing happens when I click the canvas.
I know everything is linked properly because at the top of my javascript file I have this:
function loader()
{
var canvas = $('#canvas')[0].getContext('2d');
canvas.fillStyle = "rgba(200, 0, 200, 0.5)";
canvas.fillRect(225, 105, 200, 200);
}
(In the HTML file I have <body onload="loader()">)
And that works fine and displays a pink box when I load the page.
Anyone know why this may be happening? Thanks.
Got it!
The problem was that I linked my javascript file before the jQuery file.
Basically, switched these two lines:
<script type="text/javascript" src="canvas.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>