Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why does savepng workl with eventlistener but not by call from form?

39 views
Skip to first unread message

jonas.t...@gmail.com

unread,
Nov 10, 2016, 5:35:21 PM11/10/16
to
This does not work

<!DOCTYPE html>
<html>
<body onload="createCanvasContext()">
<form name=jj onSubmit="savepng(); return false;">
<input type=submit name="" value="SAVE">
</form>
<canvas id="myCanvas" width="400" height="400" color="yellow" style="border:1px solid #444444;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>

function createCanvasContext()
{
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(200,200,100,0,2*Math.PI);
ctx.fillStyle="#FF0000";
ctx.fill();
ctx.stroke();
}

function savepng() {
var mypic = canvas.toDataURL('png');
var anobject = document.createElement('a');
anobject.href = mypic;
anobject.download = 'image.png';
}
</script>
</body>
</html>


But with eventlistener save work i do not understand why?

<!DOCTYPE html>
<html>
<body onload="createCanvasContext()">
<button id="pushit">Try it</button><br>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #000000;">
Your browser does not support the HTML5 canvas tag.
</canvas>

<script>
document.getElementById("pushit").addEventListener("click", savepng);

function createCanvasContext()
{
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(200,200,100,0,2*Math.PI);
ctx.fillStyle="#FF0000";
ctx.fill();
ctx.stroke();
}

function savepng() {
var mypic = canvas.toDataURL('png');
var anobject = document.createElement('a');
anobject.href = mypic;
anobject.download = 'image.png';
anobject.click()
}
</script>

jonas.t...@gmail.com

unread,
Nov 10, 2016, 6:47:41 PM11/10/16
to
If it is possible to get the function to save the picture by call from form maybe someone could help me out.

To be honest i do not understand what click() does i thought it was the name of the event handler that listen to the id pushit and when it is pressed savepng() is called?

But what does click() do, it can't start the eventhandler because it is inside the function that will be called from the handler, restart?

JJ

unread,
Nov 11, 2016, 9:05:46 AM11/11/16
to
In the first code, you forgot to click the newly created link like in the
second code.

> If it is possible to get the function to save the picture by call from
> form maybe someone could help me out.
>
> To be honest i do not understand what click() does i thought it was the
> name of the event handler that listen to the id pushit and when it is
> pressed savepng() is called?
>
> But what does click() do, it can't start the eventhandler because it is
> inside the function that will be called from the handler, restart?

click() simulates a click event.
It's OOP, so click() belongs to anobject.
So, anobject.click() clicks the anobject.

jonas.t...@gmail.com

unread,
Nov 11, 2016, 9:35:56 AM11/11/16
to
I can see what you say is correct but i really do not understand what it does.
I have an eventhandler that i thought did listen to a button named pushit, but that is not what is going on?

Could you explain
document.getElementById("pushit").addEventListener("click", savepng);

I thought i did listen to the buttonid "pushit" and if pressed savepng() was called, what is click here "i though it was the listener name" and why is it called as a function?

It is utterly confusing.

JT

JJ

unread,
Nov 11, 2016, 10:01:30 AM11/11/16
to
On Fri, 11 Nov 2016 06:35:50 -0800 (PST), jonas.t...@gmail.com wrote:
>
> I can see what you say is correct but i really do not understand what it
> does. I have an eventhandler that i thought did listen to a button named
> pushit, but that is not what is going on?

Yes, it does. You just don't know it. Try adding below line at start of
savepng(), so you can see it working.

alert("function is called");

Hint: open the Console (CTRL+J for Chrome, or CTRL+K for Firefox) when
you're developing JavaScript code.

> Could you explain document.getElementById("pushit").addEventListener("click",savepng);

It attach an event handler (function) to the "click" event of the element
with ID "pushit".

The code produces the same functionality as below code (but different method
of attaching an event handler). In this case, it assign a function to an
event handler variable. This is an older method.

document.getElementById("pushit").onclick=savepng;

> I thought i did listen to the buttonid "pushit" and if pressed savepng()
> was called, what is click here "i though it was the listener name" and
> why is it called as a function?
>
> It is utterly confusing.
>
> JT

When you click something, a "click" event is generated to the clicked
element. All "click" event's handler functions for that element will be
called, regardless of their function name.

The "click" in '"click" event' is the name of the event. The event itself is
an object.

Thomas 'PointedEars' Lahn

unread,
Nov 11, 2016, 10:08:21 AM11/11/16
to
It is a proprietary, legacy method, though, not even defined in WHATWG HTML.
The standards-compliant approach is to dispatch a synthetic “click” event to
the element object.

This has become a lot easier since the UI Events Specification that
deprecated the Event::init*Event() methods, with their insanely long
parameter lists, in favor of proper constructors:

anObject.dispatchEvent(new MouseEvent("click", {
view: document.defaultView,
bubbles: true,
cancelable: true
}));

[Formerly:

var mouseEvent = document.createEvent("MouseEvents");
mouseEvent.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
anObject.dispatchEvent(mouseEvent);

Lesson to be learned: Design functions/methods to accept references to
parameter/option objects, and not more than 5 arguments [unless it is a list
of values of equal meaning, see e.g. Math.max()]. Otherwise nobody is going
to remember the correct argument order, you will be sacrificing flexibility,
and the caller’s code will look like Chinese (when they are not Chinese).]

<https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events> pp.

--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

unread,
Nov 11, 2016, 10:22:04 AM11/11/16
to
JJ wrote:

> On Fri, 11 Nov 2016 06:35:50 -0800 (PST), jonas.t...@gmail.com wrote:
>> Could you explain
>> document.getElementById("pushit").addEventListener("click",savepng);
>
> It attach an event handler (function) to the "click" event of the element
> with ID "pushit".
>
> The code produces the same functionality as below code

No.

> (but different method of attaching an event handler). In this case, it
> assign a function to an event handler variable. This is an older method.
>
> document.getElementById("pushit").onclick=savepng;

AISB, at least in Chromium this replaces the first event listener that had
not been added with addEventListener(), if any, so that the referred
function is called *after* all other event listeners. Try this:

var obj = document.getElementById("pushit");
obj.onclick = function () { console.log(1); };
obj.addEventListener("click", function () { console.log(2); }, false);
obj.onclick = function () { console.log(3); };

When you click the element (and navigation to another document is not the
default action), the console would show “2” followed by “3”.

> When you click something, a "click" event is generated to the clicked
> element. All "click" event's handler functions for that element will be
> called, regardless of their function name.

The proper term is event _listener(s)_.

And as the “click” event bubbles, if its propagation upwards in the document
tree is not stopped before (Event::stopPropagation()), the “click” event
listeners of ancestor elements, if any, are triggered first in tree order,
and then in listener registration order.

Scott Sauyet

unread,
Nov 26, 2016, 4:10:26 PM11/26/16
to
Thomas 'PointedEars' Lahn wrote:

> This has become a lot easier since the UI Events Specification that
> deprecated the Event::init*Event() methods, with their insanely long
> parameter lists, in favor of proper constructors:
>
> anObject.dispatchEvent(new MouseEvent("click", {
> view: document.defaultView,
> bubbles: true,
> cancelable: true
> }));
>
> [Formerly:
>
> var mouseEvent = document.createEvent("MouseEvents");
> mouseEvent.initMouseEvent("click", true, true, window,
> 0, 0, 0, 0, 0, false, false, false, false, 0, null);
> anObject.dispatchEvent(mouseEvent);
>
> Lesson to be learned: Design functions/methods to accept references to
> parameter/option objects, and not more than 5 arguments [unless it is a
> list of values of equal meaning, see e.g. Math.max()]. Otherwise nobody
> is going to remember the correct argument order, you will be sacrificing
> flexibility, [ ... ]

Why five? That still seems far too many for almost every case. Three
seems to me a much better guideline. Of course everyone will draw these
lines differently for themselves, but I was wondering: do you have a
specific reason for that number?

-- Scott

Thomas 'PointedEars' Lahn

unread,
Nov 26, 2016, 4:48:01 PM11/26/16
to
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Lesson to be learned: Design functions/methods to accept references to
>> parameter/option objects, and not more than 5 arguments [unless it is a
>> list of values of equal meaning, see e.g. Math.max()]. Otherwise nobody
>> is going to remember the correct argument order, you will be sacrificing
>> flexibility, [ ... ]
>
> Why five? That still seems far too many for almost every case. Three
> seems to me a much better guideline. Of course everyone will draw these
> lines differently for themselves, but I was wondering: do you have a
> specific reason for that number?

Yes.

--
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

Christoph M. Becker

unread,
Nov 26, 2016, 6:11:11 PM11/26/16
to
On 26.11.2016 at 22:47, Thomas 'PointedEars' Lahn wrote:

> Scott Sauyet wrote:
>
>> Thomas 'PointedEars' Lahn wrote:
>>> Lesson to be learned: Design functions/methods to accept references to
>>> parameter/option objects, and not more than 5 arguments [unless it is a
>>> list of values of equal meaning, see e.g. Math.max()]. Otherwise nobody
>>> is going to remember the correct argument order, you will be sacrificing
>>> flexibility, [ ... ]
>>
>> Why five? That still seems far too many for almost every case. Three
>> seems to me a much better guideline. Of course everyone will draw these
>> lines differently for themselves, but I was wondering: do you have a
>> specific reason for that number?
>
> Yes.

Which is?

--
Christoph M. Becker

Thomas 'PointedEars' Lahn

unread,
Nov 26, 2016, 6:57:46 PM11/26/16
to
Maybe it was like Douglas Adams picked the number that was going to be the
“Answer to the Ultimate Question of Life, The Universe, and Everything”:

“The answer to this is very simple. It was a joke. It had to be a number,
an ordinary, smallish number, and I chose that one. Binary
representations, base thirteen, Tibetan monks are all complete nonsense.
I sat at my desk, stared into the garden and thought '42 will do'.
I typed it out. End of story.”

—Douglas Adams in <news:alt.fan.douglas-adams>,
<news:adamsd.11...@news.cerf.net>

So, why did I pick 5? It just seemed practical at the time, and it still
does. It is a reasonably small number, which is important for a short code
line length, particularly if you want to be descriptive in your parameter
names, but not so small as to be overly restrictive in a rule of thumb.
If you are human(oid), and still equipped with all fingers (or toes), you
can count the arguments/parameters of the function on those using only one
limb. Maybe it is easier to develop a mnemonic because of that.

In hindsight, there is also an oft-cited theory in the cognitive sciences
(which I learned of when studying machine-computer interaction) which is
usually interpreted so that humans’ working memory can hold up to 7 ± 2
items; so, 5 would be a number that every human(oid) could manage:

<https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two>

Finally, I think that I can remember the correct order of 5 parameters
without consuming too much caffeine.

Scott Sauyet

unread,
Nov 26, 2016, 8:09:35 PM11/26/16
to
Thomas 'PointedEars' Lahn wrote:
> Christoph M. Becker wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Scott Sauyet wrote:
>>>> Thomas 'PointedEars' Lahn wrote:

>>>>> Lesson to be learned: Design functions/methods to accept references
>>>>> to parameter/option objects, and not more than 5 arguments [unless
>>>>> it is a list of values of equal meaning, see e.g. Math.max()].
>>>>> Otherwise nobody is going to remember the correct argument order,
>>>>> you will be sacrificing flexibility, [ ... ]
>>>> Why five? That still seems far too many for almost every case.
>>>> Three seems to me a much better guideline. Of course everyone will
>>>> draw these lines differently for themselves, but I was wondering: do
>>>> you have a specific reason for that number?
>>> Yes.
>>
>> Which is?

> [... fun and relevant but somewhat long Douglas Adams quote elided ...]

> So, why did I pick 5? It just seemed practical at the time, and it
> still does. It is a reasonably small number, which is important for a
> short code line length, particularly if you want to be descriptive in
> your parameter names, but not so small as to be overly restrictive in a
> rule of thumb. [ ... ]

Would you find a rule of thumb suggesting at most three parameters overly
restrictive?

> In hindsight, there is also an oft-cited theory in the cognitive
> sciences (which I learned of when studying machine-computer interaction)
> which is usually interpreted so that humans’ working memory can hold up
> to 7 ± 2 items; so, 5 would be a number that every human(oid) could
> manage:
>
> <https://en.wikipedia.org/wiki/
The_Magical_Number_Seven,_Plus_or_Minus_Two>

Even that Wikipedia article discusses how much controversy there is
around those numbers and even with the basic idea that there really are
fixed size limits irrespective to the contents. But regardless of that,
all those experiments have to do with being able to repeat back sequences
immediately after presentation. For function parameters surely the
relevant criterion would be being able to infer the correct order even
long after learning them.

So I strive to create parameters in a particular order: the one most
conducive to currying. I try to place any parameter more likely to
change after one less likely to change. Of course this is not always
clear, and sometimes there are still judgment calls, but I think it
serves reasonably well, and it tends to make it easier to remember the
parameter order. Of course it helps that it's extremely rare that I
create a function with more than three parameters! ;-)

> Finally, I think that I can remember the correct order of 5 parameters
> without consuming too much caffeine.

Your memory must be better than mine. I have a hard enough time with
three, even with the rule above, if there's any ambiguity about which
parameter is more likely to change.

-----

Of course this is not a serious disagreement. Clearly the main rule is
to limit one's parameter list as well as one can. But I'm always curious
as to how people decide upon their particular limits.


-- Scott

Christoph M. Becker

unread,
Nov 28, 2016, 12:17:39 PM11/28/16
to
On 27.11.2016 at 02:08, Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>
>> Christoph M. Becker wrote:
>>
>>> Thomas 'PointedEars' Lahn wrote:
>>>
>>>> Scott Sauyet wrote:
>>>>
>>>>> Why five? That still seems far too many for almost every case.
>>>>> Three seems to me a much better guideline. Of course everyone will
>>>>> draw these lines differently for themselves, but I was wondering: do
>>>>> you have a specific reason for that number?
>>>>
>>>> Yes.
>>>
>>> Which is?
>>
>> [Explanation why Thomas prefers at most 5 function parameters.]

Thanks!

> Of course this is not a serious disagreement. Clearly the main rule is
> to limit one's parameter list as well as one can. But I'm always curious
> as to how people decide upon their particular limits.

FWIW, I quite like Robert C. Martin's rule regarding function
arguments[1] (even though I don't always follow it):

| The ideal number of arguments for a function is zero (niladic). Next
| comes one (monadic), followed closely by two (dyadic). Three arguments
| (triadic) should be avoided where possible. More than three
| (polyadic) requires very special justification and then shouldnt be
| used anyway.

This rule is given in an OOP context, so for functional or procedural
style most likely one should be added (niladic functional or procedural
functions rarely make sense).

[1] Clean Code: A Handbook of Agile Software Craftsmanship

--
Christoph M. Becker

Scott Sauyet

unread,
Nov 28, 2016, 9:17:13 PM11/28/16
to
Christoph M. Becker wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Christoph M. Becker wrote:
>>>> Thomas 'PointedEars' Lahn wrote:

>>> [Explanation why Thomas prefers at most 5 function parameters.]
>
> Thanks!
>
>> Of course this is not a serious disagreement. Clearly the main rule is
>> to limit one's parameter list as well as one can. But I'm always
>> curious as to how people decide upon their particular limits.
>
> FWIW, I quite like Robert C. Martin's rule regarding function
> arguments[1] (even though I don't always follow it):se

"A foolish consistency is the hobgoblin of little minds."
-- Ralph Waldo Emerson

>| The ideal number of arguments for a function is zero (niladic). Next
>| comes one (monadic), followed closely by two (dyadic). Three arguments
>| (triadic) should be avoided where possible. More than three
>| (polyadic) requires very special justification and then shouldn't be
>| used anyway.
>
> This rule is given in an OOP context, so for functional or procedural
> style most likely one should be added (niladic functional or procedural
> functions rarely make sense).

I agree. This sounds exactly right. There are of course uses of unary
functions in functional programming, but that's either at the boundary of
a program or as thunks of computation set aside to be processed if
they're actually needed. Neither has anything to do with API design.


> [1] Clean Code: A Handbook of Agile Software Craftsmanship

I don't know why that classic has never bubbled its way to the top of my
to-read list. One of these days...

-- Scott

Christoph M. Becker

unread,
Dec 2, 2016, 2:24:24 PM12/2/16
to
On 29.11.2016 at 03:15, Scott Sauyet:

> Christoph M. Becker wrote:
>
>> | The ideal number of arguments for a function is zero (niladic). Next
>> | comes one (monadic), followed closely by two (dyadic). Three arguments
>> | (triadic) should be avoided where possible. More than three
>> | (polyadic) requires very special justification and then shouldn't be
>> | used anyway.
>>
>> This rule is given in an OOP context, so for functional or procedural
>> style most likely one should be added (niladic functional or procedural
>> functions rarely make sense).
>
> I agree. This sounds exactly right. There are of course uses of unary
> functions in functional programming, but that's either at the boundary of
> a program or as thunks of computation set aside to be processed if
> they're actually needed. Neither has anything to do with API design.

Hm, did you meant "nullary" instead of "unary"? For instance, there are
several useful unary functions in Rambda.

>> [1] Clean Code: A Handbook of Agile Software Craftsmanship
>
> I don't know why that classic has never bubbled its way to the top of my
> to-read list. One of these days...

A caveat, though: the author appears to be as opinionated as Douglas
Crockford. :-)

--
Christoph M. Becker

Scott Sauyet

unread,
Dec 2, 2016, 8:59:48 PM12/2/16
to
Christoph M. Becker wrote:
> Scott Sauyet wrote:
>> Christoph M. Becker wrote:

>>> This rule is given in an OOP context, so for functional or procedural
>>> style most likely one should be added (niladic functional or
>>> procedural functions rarely make sense).
>>
>> I agree. This sounds exactly right. There are of course uses of unary
>> functions in functional programming, but that's either at the boundary
>> of a program or as thunks of computation set aside to be processed if
>> they're actually needed. Neither has anything to do with API design.
>
> Hm, did you meant "nullary" instead of "unary"?

Yes, of course.

> For instance, there are several useful unary functions in Rambda.

Well, I hope so! :-)

BTW, it's spelled "Ramda". The name, as was the name of its predecessor,
"Eweda" is simply a play on "Lambda". Rams and ewes are grown-up lambs.


>>> [1] Clean Code: A Handbook of Agile Software Craftsmanship
>>
>> I don't know why that classic has never bubbled its way to the top of
>> my to-read list. One of these days...
>
> A caveat, though: the author appears to be as opinionated as Douglas
> Crockford. :-)

To my mind that's mostly a good thing. I'd rather authors who take a
stand and stick by it. It makes it much easier to know what to discount
in their writing. ;-)

-- Scott
0 new messages