Working with JavaScript

Hi,
I turn this code into CoffeeScript:

paintIt = (element, backgroundColor, textColor) ->
element.style.backgroundColor = backgroundColor
if textColor?
element.style.color = textColor

and this code I turn to html.rb

Paint it red

it not worked fine, I see the link but it’s not Paint it red!

What Did I Do Wrong?

thank, Izik

What does your JavaScript console say? Is the compiled JS in the page
before the link appears to call it? Is the CS-generated JS wrapped in a
closure of some sort? (I’m thinking here that your function may not be
in the global scope.)

It’s much better practice to establish listeners in your script, and
invoke them lazily, rather than writing inline (so-called DOM Level 0)
scripts in your page code.

Consider this (which you must add at the very end of the page code, not
the beginning):

document.addEventListener(‘click’, evt){
if(this.tagName == ‘A’){
if(this.readAttribute(‘data-paint’)){
this.style.backgroundColor = this.readAttribute(‘data-paint’);
}
}
});

That would interact with this HTML:

Paint it red

You could extend this pattern by adding a data-text-color attribute, and
add a handler for that in the one function body. There’s probably little
difference in following this pattern versus your example when there’s a
few links on the page, but if there were thousands, this method would be
measurably faster to load and evaluate.

Walter

As Walter says, Coffeescript by default compiles to javascript like
this:

(function() {

// your code here…

}).call(this);

This creates a closure: code within it can only be accessed by other
code
within it by default. In addition to Walter’s ideas, you could:

  1. define paintIt as window.paintIt, which will force the function into
    the
    global scope, so it can be accessed anywhere. This is not ideal, as
    already
    discussed.

  2. Use JQuery or a similar library (JQuery is in your standard Rails
    project gemfile) to add a listener. It would be something like this:

paintIt = (element, backgroundColor, textColor) ->
element.style.backgroundColor = backgroundColor
if textColor?
element.style.color = textColor

$(’#paintRed’).click ->
paintIt(this, ‘#990000’)

Paint it red!

The data attribute solution is the way to go for anything more than a
few
links, however. You may nonetheless be able to reduce boilerplate by
using
JQuery to make listeners.

James Turley wrote in post #1132300:

  1. Use JQuery or a similar library (JQuery is in your standard Rails
    project gemfile) to add a listener. It would be something like this:

As you might have guessed option 2) is the RIGHT option (as opposed to
the, “It may be ugly but it works!” option").