Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts
Friday, 13 December 2013

How to remove the default Blogger assets

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>
Tuesday, 28 May 2013

Dart, my first steps

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.

Saturday, 6 April 2013

Aligning and element with background-size:cover

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.

Google
Sunday, 31 March 2013

sticky-header.js

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.

Demonstration

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.

Here is a demonstration on GitHub HTML preview, and be sure to check it out on GitHub!

Saturday, 2 March 2013

Data-bind a Knockout.js model infinitely deep

Knockout logo

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).

function Employee(name, boss) {
    this.name = name;
    this.boss = boss;
    this.employees = ko.observableArray([]);
}

Template

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.

<div data-bind="template: { name: 'organisation-template', foreach: employees }"></div>

<script id="organisation-template"  type="text/html">
    <label data-bind="attr: { 'for': nameId }">Name:</label>
    <input data-bind="attr: { 'id': nameId }, value: name" />
    <div data-bind="template: { name: 'organisation-template', foreach: employees }"></div>
</script>

The nameId property on the Employee model is included to give the name textbox a unique id so that it can have a label. Accessibility is good!

function Employee(name, boss) {
    /* the rest of the code */

    this.nameId = ko.computed(function() {
        return name.split(' ').join('_')
                   .split('.').join('_');
    });
}

Let's also go ahead and add a little CSS so we can differentiate the hierarchy levels.

.employee {
    border:1px solid #ccc;
    padding:.3em;
    margin-bottom:.3em;
}

.employee:last-child {
    margin-bottom:0;
}

Test data

Now let's create some test JSON to display on the UI initially, in practice this would normally come from a server.

var jsonModel = '{"employees":[{"name":"Jason Alexander","employees":[{"name": "George Costanza","employees":[{"name":"Art Vandelay"}]}]},{"name":"Michael Richards","employees":[{"name":"Cosmo Kramer","employees":[{"name":"H.E. Pennypacker"},{"name":"Bob Sacamano"}]}]},{"name":"Jerry Seinfeld","employees":[{"name":"Kel Varnsen"}]}]}';

Parse the JSON

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:

Databind

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;

To hook this is up the UI we need a

<button data-bind="click: addEmployee">Add employee</button>
<div data-bind="template: { name: 'organisation-template', foreach: employees }"></div>

<script id="organisation-template"  type="text/html">
    <div class="employee">
        <label data-bind="attr: { 'for': nameId }">Name:</label>
        <input data-bind="attr: { 'id': nameId }, value: name" />
        <button data-bind="click: addEmployee">Add employee</button>
        <button data-bind="click: deleteEmployee">Delete employee</button>
        <div data-bind="template: { name: 'organisation-template', foreach: employees }"></div>
    </div>
</script>

End result

And it's done! Click here to see a working example. It should look like this

End result
End result 2
Monday, 24 December 2012

Merry Christmas!

Merry Christmas everyone! Here is a CodePen of I whipped up to celebrate, a binary Christmas tree :)

See the Pen Binary Christmas Tree by Daniel Imms (@Tyriar) on CodePen

Tuesday, 20 November 2012

Debug JavaScript using event listener breakpoints

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:
  • Animation
  • Control
  • Clipboard
  • DOM mutation
  • Device
  • Keyboard
  • Load
  • Mouse
  • Timer
  • Touch
Tuesday, 23 October 2012

More on jQuery id selection performance

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.


Friday, 19 October 2012

Use prettyprint in the Chrome debugger

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.

Wednesday, 17 October 2012

jQuery attr('id') vs [0].id performance

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.

Here are the results of the test:

div.attr('id'): 1545ms
div.attr('id'): 1536ms
div.attr('id'): 1558ms

div[0].id: 48ms
div[0].id: 46ms
div[0].id: 45ms

div.get(0).id: 59ms
div.get(0).id: 69ms
div.get(0).id: 62ms

div[0].getAttribute('id'): 74ms
div[0].getAttribute('id'): 72ms
div[0].getAttribute('id'): 74ms

Monday, 15 October 2012

Web Platform Docs

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."

Tuesday, 2 October 2012

Creating a 'trail' effect in canvas

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.


Check it out here.

This is a snippet of the loop, the important part.
function loop() {
  updatePosition();
  
  // Draw over the whole canvas to create the trail effect
  context.fillStyle = 'rgba(255, 255, 255, .05)';
  context.fillRect(0, 0, canvas.width, canvas.height);
  
  // Draw the dot
  context.beginPath();
  context.fillStyle = '#ff0000';
  context.moveTo(dot.x, dot.y);
  context.arc(dot.x, dot.y, 3, 0, Math.PI*2, true);
  context.fill();
}
Friday, 24 August 2012

How to select a HTML table column using jQuery

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.
// Highlight column 2
$('table tr > td:nth-child(2), table tr > th:nth-child(2)')
    .attr('style', 'background-color:#CCF;');

// Hide column 3
$('table tr > td:nth-child(3), table tr > th:nth-child(3)')
    .hide();
Saturday, 14 July 2012

Getting around the mailto character limit

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.

Wednesday, 27 June 2012

Make tags keyboard accessible with tabindex

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.
<img id="example" tabindex="0" src="..." />
 
 
$(document).ready(function () {
  $('#example')
    .click(triggerExample)
    .keydown(triggerExample);
});

function triggerExample(event) {
  if (event.keyCode == 13 || event.keyCode == 32 ||
      event.type == 'click') {
    doExample();
  }
}

function doExample() {
  alert('Image triggered');
}
Remember that you can always test what can be accessed with the keyboard by hitting the tab key.
Sunday, 24 June 2012

Easy sortable HTML tables using jQuery

I made a little jQuery script that makes it really easy to enable sorting on a HTML table.

Features

  • Really easy to set up
  • Can sort on load if a header is specified otherwise assumes that the first column is already sorted
  • Keyboard accessible
  • Adds title attributes automatically to each th
  • CSS arrow to signify ascending or descending

Thursday, 14 June 2012

Passing parameters to jQuery event handlers

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.
<html>
<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

  <script type="text/javascript">
    $().ready(function () {
      $('button#one').click({ text: 'first button' }, handleClick);
      $('button#two').click({ text: 'second button' }, handleClick);
    });

    function handleClick(event) {
      alert('Clicked on the ' + event.data.text);
    }
  </script>

</head>
<body>
  <button id="one">button#one</button>
  <button id="two">button#two</button>
</body>
</html>
Saturday, 9 June 2012

Using google-code-prettify in your blog

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:
<div style="background-color: #f0f0f0; border: 1px dashed #CCCCCC;">
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: red; font-family: Consolas; font-size: 9.5pt;">position</span><span style="font-family: Consolas; font-size: 9.5pt;">:<span style="color: blue;">fixed</span>;<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: red; font-family: Consolas; font-size: 9.5pt;">top</span><span style="font-family: Consolas; font-size: 9.5pt;">:<span style="color: blue;">50%</span>;<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: red; font-family: Consolas; font-size: 9.5pt;">left</span><span style="font-family: Consolas; font-size: 9.5pt;">:<span style="color: blue;">50%</span>;<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: red; font-family: Consolas; font-size: 9.5pt;">width</span><span style="font-family: Consolas; font-size: 9.5pt;">:<span style="color: blue;">200px</span>;<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: red; font-family: Consolas; font-size: 9.5pt;">height</span><span style="font-family: Consolas; font-size: 9.5pt;">:<span style="color: blue;">150px</span>;<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: red; font-family: Consolas; font-size: 9.5pt;">margin-top</span><span style="font-family: Consolas; font-size: 9.5pt;">:<span style="color: blue;">-75px</span>; <span style="color: darkgreen;">/* negative half height */</span><o:p></o:p></span></div>
<span style="color: red; font-family: Consolas; font-size: 9.5pt; line-height: 115%;">margin-left</span><span style="font-family: Consolas; font-size: 9.5pt; line-height: 115%;">:<span style="color: blue;">-100px</span>;
<span style="color: darkgreen;">/* negative half width */</span></span></div>
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:
Thursday, 31 May 2012

Creating custom objects in JavaScript

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();
Easy.

JavaScript arrays

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'];