WARNING This is a tutorial designed for expert web developers, following this tutorial can break the template customiser, layout customiser and prevent widgets from being added to your blog. Your blog may also depend on them if you haven't heavily customised the template.
The default Blogger assets have plagued me ever since I started to dive deep into the Blogger template to make my design nicer and to drive the page load time down. A Blogger template requires several tags in the <head> and the editor will refuse to apply the template without them, namely this section.
<b:include data='blog' name='all-head-content'/>
<b:skin>
<![CDATA[/*
-----------------------------------------------
Blogger Template Style
Name: Some name
Designer: Some author
URL: Some URL
----------------------------------------------- */
...A lot of CSS...
]]>
</b:skin>
<b:template-skin>
<b:variable default='960px' name='content.width' type='length'/>
<b:variable default='0' name='main.column.left.width' type='length'/>
<b:variable default='310px' name='main.column.right.width' type='length'/>
<![CDATA[
...A lot of CSS...
]]>
</b:template-skin>
A couple of weeks ago I jumped in to Dart with a little project to learn the language; to convert my canvas-astar.js project. I'm glad to say that what Google claims is true, since Dart borrows syntax from some common languages, it's very easy for the seasoned developer to learn. It took me around an hour of studying and then an hour of porting to get it in the state that it is.
JavaScript → Dart
Much of the JavaScript actually turned out to be valid Dart as well, this makes porting a JavaScript application to Dart dead simple. I went the statically-typed route which took a little longer but it was a very quick and easy process.
The CSS property background-size:cover is incredibly useful but due to the nature of it resizing in different directions, it's difficult to pinpoint where a particular part of the image is on the background at any given time. Difficult but not impossible of course.
To do this you first need to understand how background-size:cover works. Basically the image will fill the screen at all times by stretching out while maintaining aspect ratio. This means that unless the window is perfectly sized to fit the image, either the image is going to be cut off at the top and bottom edges, or the left and right edges.
Given this we can calculate the scale of the image and the x or y offset to find out the actual coordinates of the target location. I've created a little example using Google's logo that positions a red dot inside the red 'o' character. Resizing the window will keep the red dot inside the 'o' no matter how you resize the window.
I wrote up a little JavaScript plugin over the weekend that has a <table>'s header scroll with the page. What sparked this little endeavour was a question asking for this functionality on Stack Overflow. Since it was fun answering the question, I thought I'd go ahead and make a more general plugin type solution that worked for multiple tables.
Similar to my sortable-table.js plugin, simply add the sticky-header class to a <table> and the functionality will be enabled.
<table class="sticky-header">
....
</table>
I've tested it in all the latest browsers and seems to work fine; Chrome, Firefox, Safari, Opera, IE10, IE9 and IE8. No IE7 because it doesn't implement querySelectorAll, the code would be a bit more icky if I used some other method, and you know, it's IE7.
This post will show you how to data-bind a hierarchical model that can go infinitely deep onto a page using Knockout.js. In this post, I will make a screen that will be used to build an organisation chart as an example, I chose this as it's a really simple example to illustrate the technique that I'll be using.
Model
First we create the model that we want to bind to the UI. Our model is of an employee that will have a name, a link to it's boss and array of employees (subordinates).
The template is used to display the model, our template will iterate over an array of employees, show their name and point back to itself to do it again with each of the employee's subordinates.
Now we will create the model from the JSON model that was defined in the above section.
function OrganisationViewModel() {
initialiseModel(this, jsonModel);
}
function initialiseModel(model, jsonModel) {
parsedModel = JSON.parse(jsonModel);
model.employees = ko.observableArray([]);
addEmployees(model, parsedModel.employees);
console.log(model);
}
function addEmployees(bossModel, employees) {
if (typeof employees === "undefined")
return;
for (var i = 0; i < employees.length; i++) {
var employee = employees[i];
var employeeModel = new Employee(employee.name, bossModel);
bossModel.employees.push(employeeModel);
addEmployees(employeeModel, employee.employees);
}
}
Data bind
Finally everything is ready to data bind!
ko.applyBindings(new OrganisationViewModel());
It should look like this now:
Add/delete buttons
We also want to be able to add and delete employees, start by creating the JavaScript functions and attaching them to the model. Notice that we're reusing the addEmployee function on OrganisationViewModel as well to create out root-level employees.
function addRule() {
var newRule = new Rule('Fresh rule', this);
this.rules.push(newRule);
}
function deleteRule() {
var parent = this.parent;
parent.rules.splice(parent.rules.indexOf(this), 1);
}
OrganisationViewModel.prototype.addEmployee = addEmployee;
Employee.prototype.addEmployee = addEmployee;
Employee.prototype.deleteEmployee = deleteEmployee;
Have you ever started working on a giant project containing many JavaScript files and needed to find out what some random button is doing? A pretty easy way to find out is to enable the mouse click's event listener breakpoint in the Chrome developer tools. This will break execution when you next click on the page allowing you to step into the code seeing exactly what is happening.
To set an event breakpoint hit F12 to open the developer tools, go to the Sources tab and check one of the events on the right sidebar.
Chrome (23) allows you to break on several events in each of the the following event groupings:
In response to Ron's comment on the attr('id') vs [0].id post last week asking about the jQuery.fn.prop's vs jQuery.fn.attr's performance, I extended the program to include prop and enabled profiling across all browsers (thanks to time.js). The program also does the tests a little more thoroughly, running 1000000 operations 5 times per each operation and averages the result.
Some of the result surprised me a little, in particular Safari beating Chrome on d.attr('id') but nothing else, and d.prop('id') was the clear winner.
In version 12 of Chrome they added the ability to de-obfuscate (un-minify?) the JavaScript on the sources tab by right clicking the code area. Today that feature lives on in the "pretty print" feature located at the curly brace icon on the bottom of the debugger.
So I was wondering for a while exactly what the performance difference is between the jQuery function attr('id') and getting the native JavaScript object and grabbing the id that way was. Surely attr('id') was slower but how much slower... I decided to write a little HTML page that tested each method by doing 1 million operations of each. In interest of being complete I added the getAttribute and get(0).id methods also.
So www.webplatform.org was released 5 days ago and people seem to be really keen to get it up and going. For those of you who don't know Web Platform was created with the following goal in mind, taken from the welcome blog post.
"The goal of this site is to be the place to come for answers to your trickiest (and simplest) development and design questions about the Open Web Platform."
I put together a CodePen demonstrating a method for creating a 'trail' effect using canvas. The method involves drawing a slightly transparent rectangle over the canvas every time the program loops. This creates the fading gradient effect.
Here is a method for selecting a column in a table using the selector :nth-child(n). You could then do whatever you want to it, like hiding or highlighting it. An example use could be showing that a particular column has been sorted, instead of the more tranditional method of showing some indicator on the header.
I was faced with a problem recently where a web page needed to create an email with the user's email client. This is normally trivial, simply redirect the user to mailto:<emails>. The issues was that the maximum length of a URL across different platforms is approximately 2000 characters, and the amount of emails required far exceeded that in some cases. So a solution would need to make multiple mailto requests.
HTML elements such as div, span, img, etc. don't normally accept input, but sometimes you'll want them to. For example if you have an image that does something when you click on it. If you want your site to be accessible it also needs to happen when you tab to the element and press enter.
There are two parts to this; giving the element a tab index and then hooking up the event. For the tab index simply set the tabindex attribute on the tag to 0 and the user will be able to navigate to the tag using the tab key. The following javascript snippet adds the event handlers using jQuery and shares the function (triggerExample) that is doing the work between both keydown and click events.
Something everyone who works with jQuery should know, how to pass parameters to a jQuery event handler. Pass a data object as the first argument on the event, the contents of the object will be transferred onto the data variable of event.
Until now to make my source code pretty I've used a pretty dodgy method that involved going from Visual Studio to Word to Blogger and surrounding the lot in a div to apply some styles to the whole thing. This has resulted in HTML source looking something like this:
Disgusting I know, not only does it look gross but it also makes it a lot more difficult to work on posts using my mobile. So I decided to look into a prettyprint alternative, I found google-code-prettify as one of the first search results and went into investigate. It is a very simple process to get it up and running using the following steps:
I always assumed JavaScript had the ability to create custom objects but only bothered learning how to do so recently. Turns out it's incredibly easy to create custom "objects" with parameters.
function CustomObject(a, b) {
this.a = a;
this.b = b;
this.c = a + b;
this.print = printParams;
}
function printParams() {
alert(this.a + ',' + this.b + ',' + this.c);
}
var obj = new CustomObject(2, 3);
obj.print();
This post will go over the capabilities and syntax of arrays in JavaScript.
Initialisation
Here are the different methods for initialising arrays:
// first method
var a = [];
a[0] = 'a';
a[1] = 'b';
a[2] = 'c';
// second method
var b = new Array('a', 'b', 'c');
// third method
var c = ['a', 'b', 'c'];