Sign in

A quick crash course in Neon

Thanks for giving Neon a try. This beginners' tutorial will give you a step-by-step introduction to many of Neon's basic features, and demonstrate some of what Neon is capable of.

Installing Neon

The file neon.js contains the core library. To get started with Neon, include this file within the <head> section of your page after any stylesheets, and before any other scripts:

<script src="/path/to/neon.js"></script>

Including the Neon library like this allows you to access the Neon global object neon in any Javascript on your page.

Here is a sample statement using Neon, enclosed within <script> tags as you would in your HTML. Notice that the statement begins with neon. The rest of the line containing the statement will be explained later in this tutorial.

<script>
neon.select("body").append({p:"This is a test."});
</script>

Selecting elements

When writing Javascript for a web application, it's frequently necessary to locate certain elements from the current page, before you can do things with them. Neon makes this easy, using a selection system based on CSS-style selectors.

// Select all link elements within our header
var links = neon.select("#header a");

After selecting elements in a Neon object, we can add more Neon methods onto the end of the same line. The methods then act on the selection that was made. This is called “chaining”. This often prevents the need to save the selection into a temporary variable.

// Add an inline style to these elements
neon.select("#header a").style("color", "blue");

The above code added an inline style to our elements—but that's not very remarkable as it's something we could have done using just HTML and CSS. We might, however, chain the watch() method to watch for an event on those elements and run code when that event happens:

// Execute function when a header link is clicked
neon.select("#header a").watch("click", function() {
alert("A link was clicked");
});

Notice how we define a function inside the second argument to watch(). We could, however, have defined the function separately and given a reference to it instead.

We can also append new elements into the document:

// Add a new link to a menu
neon.select("#mylist").append({li:"New list item"});

This command has added an li element with the text contents "New list item". You'll learn more about building new elements later.

How complex can we get with our selectors? On recent versions of all browsers, Neon supports all CSS selectors that the browser supports, which will ensure good support for modern CSS. On older browsers (primarily Internet Explorer 6 and 7), Neon will support a minimum subset of CSS 2.1 selector syntax, even where the browser wouldn't support that syntax in its own CSS engine. For instance, the following syntax elements are supported across browsers:

  • A > B
  • A + B
  • A:first-child
  • [attr=value]

Building new elements

Neon allows us to easily create new elements using a simple syntax, and insert them into the document. We already saw an example of this previously:

// Add a new link to a menu
neon.select("#mylist").append({li:"New list item"});

Here, we are appending a new list item to the end of the list, using the following object syntax:

{li: "New list item"}

The key comes first, and refers to the element's tag name. Then the value refers to the element's content—in this case just some text. If we wanted an empty li element instead, we could have used null (or an empty string, for brevity) in place of the string.

To add attributes to the element, we can add them as new keys preceded by a dollar sign ($). Here, we can add a title attribute to our list item:

{li: "New list item", $title: "This is the title attribute"}

The dollar sign simply makes it easier to distinguish attributes from the element name (and means that the order of properties doesn't matter).

So far, we have created only one element at a time, but it's also possible to nest elements. For example, the following represents a link inside a list item:

{li: {a: "Click here", $href: "http://neonjs.com"}}

Notice the two layers of objects signified by the two layers of curly braces.

Multiple children can be added to an element using array notation (square brackets). In this case, let's create an unordered list with two list items:

{ul: [{li: "List item 1"}, {li: "List item 2"}]}

That pretty much covers the basic building blocks of creating elements. There is no limit to the number of elements nested inside other elements that can be created at once. You could store or transmit whole documents this way if you desired, and this encoding is JSON compatible.

Neon provides a few methods which can build new elements:

  • append(): inserts the new elements as children of the selected element

  • insert(): inserts new elements before the start of the selected element

  • build(): creates the new elements and returns them, but does not insert them into the document (yet)

.append() and .insert() can also be used to move existing elements around in a document. If you pass one or more existing elements as their argument, instead of an object structure as defined above, it will move those objects from their current location instead.

Watching for events

Neon's watch() and unwatch() methods allow you to set and clear event handlers, allowing you to respond to events on certain elements. Event handlers are set the same way on all supported browsers, removing most browser-specific incompatibilities.

This is the basic way of setting an event handler:

// Register an event to run the function "myfunction" when the button is clicked
neon.select("#button").watch("click", myfunction);

When we called the watch() method, we provided the name of the event to handle, and a function that should execute when the event is triggered. In this case, we are only watching click events that occur on the #button element—though we could have selected any events or elements to watch.

The event name should not include “on” at the start of its name; this should be omitted.

Example event names are:

  • click

  • keydown

  • mouseenter / mouseleave (useful for “hover” actions)

  • submit (for a form)

Your browser will support a lot more than this. Note that mouseenter and mouseleave are synthesized so that they are supported on all browsers, making them usable cross-browser.

A variety of information is passed to our event handling function when it is called. From this information, it is possible to know which element the event was triggered on, which mouse button was pressed (for mouse events), which key was pressed (for keyboard events), and more. This information is provided through an evt object, provided as a parameter to the function.

Here's a selection of useful properties and members of the evt object:

  • preventDefault(): this method can be called to suppress the browser's default action (such as submitting a form or following a link)

  • which: a value specifying which mouse button was pressed, or which key was pressed

  • pageX, pageY: the coordinates of the mouse click, relative to the document

  • target: a reference to the DOM element which originally triggered the event

There are plenty of others. The target property can be particularly useful when the element you are watching has children. If the event originated in one of these children, this property will refer to the child where the event occurred. This is particularly powerful, because it allows you to watch for events on many elements at once just by watching a common parent—this is known as event delegation.

Stop watching events

Just as watch() allows you to register a function to listen for an event, unwatch() allows you to end such registration. This is useful for when you're no longer interested in watching for this event.

You will need to provide the same function reference that was used to register earlier.

// Stop watching for clicks on this button
neon.select("#button").unwatch("click", myfunction);

Waiting until the document is ready

If you've loaded your Javascript by including a <script> element in your page head, your Javascript will be executed before the rest of the page has loaded. This presents problems if you need to interact with elements on the page that haven't loaded yet.

You could simply place your Javascript later in your code than all the elements you wish to interact with. But if you like the idea of keeping your code separate and unobtrustive, you may want another way.

Neon's ready() method allows you to wait until the document has downloaded before executing your setup scripts:

neon.ready(function() {
// Place all your setup code here
});

Any commands inside the callback function will be called once the document structure has fully loaded. Note that it won't necessarily wait until content such as images and plugins load, but at least all of the DOM elements in the page will have loaded and can be interacted with.

If you keep your Javascript separate to your HTML, it's not unusual to make extensive use of .ready()—perhaps even using it to launch the bulk of your code.

Setting inline styles

Setting an inline style on one or more elements is very simple. Just use the style() method to specify the style you want to change, and the value you want to give it.

// Give text inputs a yellow background
neon.select("#myform input[type=text]").style("background", "yellow");

Of course, multiple style changes can be chained:

// Give text inputs a yellow background
neon.select("#button")
.style("background", "yellow")
.style("color", "#000")
.style("width", "80%");

Making use of styles defined in external stylesheets

While it's very convenient to set inline styles in the way described above, you should also consider defining your styles in your external stylesheets, and assigning them to classes. This allows you to continue to keep your style definitions separate to your code, tucked away in your CSS stylesheets.

Assuming you want to be able to switch a button to showing a yellow background, you could assign a class name to this action. In this case, we'll call the class "highlighted" because that roughly describes the action we're taking. The above example could be rewritten as:

// Stylesheet
#button.highlighted {
  background: yellow;
  color: #000;
  width: 80%;
}
// Javascript code
neon.select("#button).addClass("highlighted");

Removing the class from that element is just as easy. Substitute addClass() with removeClass().

// Remove highlighting from button
neon.select("#button).removeClass("highlighted");

Animation

Animating a style property doesn't take much more effort than setting an inline style: you just need to give two style values rather than one. The animation will initially set the style to the first value, then over time will adjust it to end with the final value.

Here, we expand the width of a div from zero to 300 pixels. The animation will start immediately and end a short while later.

neon.select("#mydiv").style("width", "0px", "300px");

When animating a style property, it's important to use the same unit of measurement to specify both values, and for the unit of measurement to be present even if a value is zero.

By default, your animation will be fairly short (about 400 milliseconds) and will use the “out” easing. This easing will cause movement to start quickly at first, and gradually slow down, like flicking a card across a table. There are further optional arguments which can be used to control the duration and easing.

// Force the animation to take 3 seconds
neon.select("#mydiv").style("width", "0px", "300px", 3000); // Use linear easing (and 600 milliseconds)
neon.select("#mydiv").style("width", "0px", "300px", 600, "lin");

Other useful easings include:

  • “in”: start slowly and accelerate, like a gravitational pull

  • “inout”: start slowly, speed up, then decelerate at the end smoothly

  • Or you could specify you own easing curve by writing a function, and passing that as a parameter in place of one of the above strings.

You can even set a function to execute once the animation finishes, which could be useful if you want to fade something out, then remove it once the fade ends.

// Fade out opactity, then call a function
neon.select("#mydiv").style("opacity", "1", "0", null, "lin", function() {
alert("Fading has finished!");
});

Notice how the duration was set to null—this will just cause the default value to be used.

Animations in Neon are quite powerful. It's all right to have many animations performing simultaneously, or overlapping. Neon is smart enough to use the same Javascript timer internally.

Since you can select multiple elements with select(), you can animate the same property on all those elements at once with a single call. It's also safe to interrupt an animation before it is finished by starting another animation on the same property, or by setting a static value to that property. If you selected multiple elements to animate, it's even safe to interrupt the animation of some of those elements but not others. The callback function will be executed as normal if any animations succeed to the end.

Setting style rules

Just as you can set inline styles on a per-element basis, Neon allows you to set up a style rule to apply to the entire document:

// Make all top level headers green on yellow
neon.styleRule("h1", "color: green; background: yellow");

The style rule will simply be added to the document's current stylesheet. The major benefit to this is that as new elements are created which match the rule, or the classes or attributes change on existing elements, the browser will continue to apply these styles according to their rules. Another benefit is that it allows CSS code on the page to override your suggested style rules, which can be useful in allowing an application's own CSS file to override the styles set by Neon.

Unfortunately, animation is not possible on a document style rule. It's also not recommend that you set a particular rule more than once, as they will accumulate as extra entries in the document's style sheet and a browser is likely to start ignoring styles after it has seen an excessive number.

Getting the current style of an element

Neon's getStyle() method allows us to find out about an element's current style. It is not limited to reading only styles to which we have explicitly set a value—the browser's built-in styles are taken into account.

// Find the width of a button
var width = neon.select("#button").getStyle("width");

The resulting value will be a string, and if it's a length value it will contain the unit of measurement (usually “px”). Note that different browsers may return values in subtly different formats.

And more...

This tutorial has demonstrated some of Neon's basic features and how to use them, including selecting elements, building new elements, setting and getting styles, and animation.

Neon also allows you to:

It's also possible to easy extend Neon with your own methods and properties.