Standard CSS3 Selectors

April 21, 2012

Here’s a table with all the standard CSS3 selectors. This is a really great reference and this can be used to either query nodes using dojo.query or to use in a browser which supports these. Most modern browsers do, IE versions will have quirks as usual so don’t rely on this in Internet Explorer 8 and below. Also, this table is from the above linked dojo.query page, I just find it very useful to have it handy during programming.

* any element
E an element of type E
E[foo] an E element with a “foo” attribute
E[foo=”bar”] an E element whose “foo” attribute value is exactly equal to “bar”
E[foo~=”bar”] an E element whose “foo” attribute value is a list of space-separated values, one of which is exactly equal to “bar”
E[foo^=”bar”] an E element whose “foo” attribute value begins exactly with the string “bar”
E[foo$=”bar”] an E element whose “foo” attribute value ends exactly with the string “bar”
E[foo*=”bar”] an E element whose “foo” attribute value contains the substring “bar”
E[hreflang|=”en”] an E element whose “hreflang” attribute has a hyphen-separated list of values beginning (from the left) with “en”
E:root an E element, root of the document
E:nth-child(n) an E element, the n-th child of its parent
E:nth-last-child(n) an E element, the n-th child of its parent, counting from the last one
E:nth-of-type(n) an E element, the n-th sibling of its type
E:nth-last-of-type(n) an E element, the n-th sibling of its type, counting from the last one
E:first-child an E element, first child of its parent
E:last-child an E element, last child of its parent
E:first-of-type an E element, first sibling of its type
E:last-of-type an E element, last sibling of its type
E:only-child an E element, only child of its parent
E:only-of-type an E element, only sibling of its type
E:empty an E element that has no children (including text nodes)
E:link
E:visited an E element being the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited)
E:active
E:hover
E:focus an E element during certain user actions
E:target an E element being the target of the referring URI
E:lang(fr) an element of type E in language “fr” (the document language specifies how language is determined)
E:enabled
E:disabled a user interface element E which is enabled or disabled
E:checked a user interface element E which is checked (for instance a radio-button or checkbox)
E::first-line the first formatted line of an E element
E::first-letter the first formatted letter of an E element
E::selection the portion of an E element that is currently selected/highlighted by the user
E::before generated content before an E element
E::after generated content after an E element
E.warning an E element whose class is “warning” (the document language specifies how class is determined).
E#myid an E element with ID equal to “myid”.
E:not(s) an E element that does not match simple selector s
E F an F element descendant of an E element
E > F an F element child of an E element
E + F an F element immediately preceded by an E element
E ~ F an F element preceded by an E element

Below are a few common operations one might come across. I’ve used Array.map() and Array.forEach() at times which requires JavaScript 1.6 or higher, but I’m not sure if older versions of Internet Explorer would support them. You might have to use a regular for loop there or use a library like Dojo, etc.

To check if an element exists in a 2-D array – Needle in a Haystack


function findNeedle(num) {
  var arr = [[2, 3, 5], [6, 8, 9], [14, 16, 19], [44, 66, 67]];
  for (var i = 0; i < arr.length; i++) {
    if (arr[i][0] > num) {
      return (arr[i - 1] ? arr[i - 1].indexOf(num) > -1 : false);
    }
  }
}

console.log(findNeedle(8)); // this one is faster because it just looks at the first element of each array.

function findNeedle2(num) {
  var arr = [[2, 3, 5], [6, 8, 9], [14, 16, 19], [44, 66, 67]];
  var flattenedArr = arr.map(function(item) {
    return item.join();
  });

  return flattenedArr.join().indexOf(num) > -1;
}

console.log(findNeedle2(3));  //this one constructs a big string out of the whole array and then does an indexOf on it.

To check if 2 arrays are equal:

function checkIfEqual(arr1, arr2) {
  if (arr1.length != arr2.length) {
    return false;
  }
  //sort them first, then join them and just compare the strings
  return arr1.sort().join() == arr2.sort().join();
}
var arr1 = [2, 3, 5, 6];
var arr2 = [5, 6, 2, 3];

checkIfEqual(arr1, arr2);

To convert an arguments object in a function to an Array, do this:

function add() {
 return [].slice.call(arguments); // note that Array.prototype.slice.call works as well, but [].slice is concise and cool
}

console.log(add(2,3,5));

Comma separated numbers:

//formats 10000045.555 as "10,000,045.555", etc
var num = 10000045.555;
//convert to string and split the string into two if there's a decimal point
var strArr = (num + '').split('.');
var n = strArr[0];

//if there's a decimal, store it
var rhs = strArr.length > 1 ? "." + strArr[1] : '';

//with the whole number, split the last 3 digits, put it at the 0th index of the array
var arr = [];
while(n.length > 3) {
 arr.unshift(n.substring(n.length - 3, n.length));
 n = n.substr(0, n.length -3);
}
//anything left in the string, add it to the start of the array
(n.length > 0 ) ? arr.unshift(n) :'';

console.log(arr.join() + rhs);

To capitalize a word:


//note how you can access the first character of a string, or its 0th index like you would for an array. You can also do str.charAt(0).

var str = "brian";
str = str[0].toUpperCase() + str.substring(1,str.length);

To check if a String is a palindrome – “word that may be read the same way in either direction”

//when you split a string, it coverts to an array, which you can reverse and re-join it which gives you a String.
var str = "abba";
str.split('').reverse().join('') == str

Note that String “literals” are not always equal to String objects.

var a = 'a';
var b = new String('a');
a == b; // true
a === b; // false, because === checks for type AND value

typeof a; //"string"
typeof b; // "object"

//valueOf() fixes this

a.valueOf() === b.valueOf() //true

If a number is too long so that it cant be represented as a number but instead needs a String representation – you need a special way of performing operations on it. For example: to subtract 1 from a really long number(represented as a String)

function subtractOne(num) {
 if(num[num.length-1]*1 === 0) {
 return subtractOne(num.substr(0, num.length-1)) + '9';
 }
 else {
 return num.substr(0, num.length-1) + ('' + num.charAt(num.length-1)*1 -1);
 }
}

subtractOne('1890273492865564687318970981034899286348912374'); //prints "1890273492865564687318970981034899286348912373"

I came across this JavaScript quiz on a very cool blog and since I really enjoy solving such problems, I took the quiz. The result was humbling, and I was eager to find out why I got some of the questions wrong. I figured out why each problem behaves the way it does so I put them together for others below.

1. (function(){
      return typeof arguments;
    })();

(a) “object” (b) “array” (c) “arguments” (d) “undefined”

The answer is (a). The arguments array is of type “object”. My first instinct was to think its an array, until I realized there was a typeof to be considered.

2. var f = function g(){ return 23; };
    typeof g();

(a) “number” (b) “undefined” (c) “function” (d) Error

This results in an error because the function g has been assigned to the var f. So the answer is (d)

3. (function(x){
      delete x;
      return x;
    })(1);
  

(a) 1 (b) null (c) undefined (d) Error

I made the mistake of assuming I could delete x, but apparently you cannot delete arguments inside a function. So the answer is 1 which is option (a).

4. var y = 1, x = y = typeof x;
    x;
  

(a) 1 (b) “number” (c) undefined (d) “undefined”

The answer here is “number”, because after assigning a value of 1 to y, x is also assigned that value. Doing a typeof on 1 obviously yields “number”.

5. (function f(f){
      return typeof f();
    })(function(){ return 1; });
  

(a) “number” (b) “undefined” (c) “function” (d) Error

Notice that we pass a function which returns 1 to the function f, which inturn executes the passed function and evaluates the type of the returned value. So typeof 1 results in “number” which is option (a)

 6. var foo = {
      bar: function() { return this.baz; },
      baz: 1
    };
    (function(){
      return typeof arguments[0]();
    })(foo.bar);
 

(a) “undefined” (b) “object” (c) “number” (d) “function”

This returns “undefined” because when the foo.bar function is executed, “this” refers to the window scope which ofcourse knows nothing about baz. How do you fix this?
Remember how to use JavaScript’s call() and apply()? If not, check here
In this case, we need to specify the “this” to be the object “foo”, like this:

 var foo = {     
      bar: function() { return this.baz; },
      baz: 1
    };
    (function(){
      return typeof arguments[0].call(foo);
    })(foo.bar);
    
7.  var foo = {
      bar: function(){ return this.baz; },
      baz: 1
    }
    typeof (f = foo.bar)();
  

(a) “undefined” (b) “object” (c) “number” (d) “function”

The above returns “undefined” because assigning foo.bar to a global variable “f” means the value of “this” inside foo.bar is “window”, and again, since window would not have a baz property, the value is undefined.

 8. var f = (function f(){ return "1"; }, function g(){ return 2; })();
    typeof f;
  

(a) “string” (b) “number” (c) “function” (d) “undefined”

This one tripped me up! The comma apparently executes the function on its right. “,” is a left-associative operator which returns the value on its right, which makes the above to be var f = 2. typeof 2 will return “number” which is option (b).

 9. var x = 1;
    if (function f(){}) {
      x += typeof f;
    }
    x;
  

(a) 1 (b) “1function” (c) “1undefined” (d) NaN

This returns “1undefined” because x+ typeof f where “f” is undefined returns 1 + “undefined” = “1undefined”. Also note how if(function(){}) evaluated to true.

10.  var x = [typeof x, typeof y][1];
    typeof typeof x;
  

(a) “number” (b) “string” (c) “undefined” (d) “object”

typeof “y” which is undefined returns “undefined”, typeof “undefined” is “string”, and another typeof on it still returns “string”.

11. (function(foo){
      return typeof foo.bar;
    })({ foo: { bar: 1 } });
  

(a) “undefined” (b) “object” (c) “number” (d) Error

This one is simple, typeof foo.bar is a trick question because the argument foo is just an object, so to really get the “bar” value, it has to be typeof foo.foo.bar in this case. Either way, the answer is “undefined”.

12. (function f(){
      function f(){ return 1; }
      return f();
      function f(){ return 2; }
    })();
  

(a) 1 (b) 2 (c) Error (e.g. “Too much recursion”) (d) undefined

I made the mistake of thinking the value is 1, but if you pay careful attention, you’ll realize both functions are called f, which means when return f() executes, function returns value 2 because its been parsed second. So the answer is “2″.

13. function f(){ return f; }
    new f() instanceof f;
  

(a) true (b) false

This evaluates to false because new f() returns a function which is not an instanceof the function f.

14. with (function(x, undefined){}) length;
  

(a) 1 (b) 2 (c) undefined (d) Error

This evaluates to 2, because the functions length is the number of expected arguments.

Facebook allows you to subscribe to an application user’s activity on Facebook, so that you can subscribe to them, and use that information for various things. This is great because (the other alternative is) having to run a daemon process in order to find out a user’s Facebook activity is painful.

However, as awesome as this service is, understanding their documentation on this topic is a whole another matter. I found it almost impossible to decipher, as a lot of things were unclear or left unexplained. Look here: http://developers.facebook.com/docs/reference/api/realtime/

Luckily I found a blog post explaining how to do this, here it is.

I’ll run down the steps again below, as a few of the steps are now easier:

1. Get access token: https://developers.facebook.com/tools/access_token/ gives you access tokens to all your apps on facebook.

2. Check if access token works:

curl "https://graph.facebook.com/<appid>/subscriptions?access_token=<access token from  step (1)>"

Since you originally have no subscriptions, you get:

{“data”:[]} or some kind of error.

3. If you got empty JSON back in step 2, now you can subscribe to updates(here I want to subscribe to user checkins):

curl -F 'object=user' \
-F 'callback_url=<callback url you have to implement>' \
-F 'fields=checkins' \
-F 'verify_token=<secret token>' \
"https://graph.facebook.com/<your-app-id>/subscriptions?access_token=<access token from (1)"

The callback_url should be something along the lines of: https://github.com/facebook/php-sdk/blob/master/examples/example.php

This call should return “null” if successful. Once you have subscribed to updates, Facebook starts posting activities of all your application users to the callback_url above.

4. To verify step 3 was successful, run step 2 again, and this time, it should return something like this:

{"data":[{"object":"user","callback_url":"http:\/\/yourdomain.com\/callback.php","fields":["checkins"],"active":true}]}

The above response means the subscription to updates about user checkins are now active. Hopefully this helps people who are confused about how to get real time updates working.

Your application might want to use a user’s checkin data in various ways, I outline below how to fetch a user’s facebook checkin information and get the Facebook page for that location.

First of all, you need to have the permissions to access a user’s checkin data. Look at http://developers.facebook.com/tools/explorer for information on this.

Once you have the required permissions and the user is logged in via Facebook connect:


//dojo.hitch to make the object scope available
FB.api("/me/checkins", dojo.hitch(this, function(response){
	if(response.data && response.data.length > 0) {
		dojo.forEach(response.data, function(item) {
            var locationId = item.id; 
            var locationName = item.place.name; //name of the place
            // To get a Facebook link to the location
            var locationLink = this.getLocationLink(locationName, locationId);
            console.log(locationLink); //print location link
        });
	}
}));

/**
* Output like this: http://www.facebook.com/pages/Espetus-Churrascaria-Brazilian-Steakhouse/166393336742282
*/
getLocationLink: function(locationName, locationId) {        
        var baseURL = 'http://wwww.facebook.com/pages/';
        var locationNameArr = locationName.split(' ');
        var locationLink = '';
        for(var i = 0; i < locationNameArr.length; i++) {
            locationLink += locationNameArr[i];
            if(i != locationNameArr.length-1) locationLink += "-";
        }        
        return baseURL + locationLink + '/' + locationId;
    },
    

More information on whats available with the Checkin object is outlined here: http://developers.facebook.com/docs/reference/api/checkin/

The /me/checkins request usually returns the most recent 25 checkins, with a hook to access more of the checkin information if required.

To use facebook connect on your website, or to allow a user to login to your website using facebook, its important to use Facebook Connect. I prefer doing this via JavaScript because its the language I am most comfortable with.

Basics on how to set up and register a facebook app have been covered elsewhere, over here I’m going to focus on the code which makes this happen.

To get started, make sure you import the Facebook JavaScript file. You also need to add a div whose id is fb-root, and you also specify your application credentials. For example:


<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
  FB.init({
    appId  : 'YOUR APP ID',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
  });
</script>

Once you do this, the FB object becomes available for use in your application. The best way to invite the user to login and/or provide permissions to your application is to use the FB.getLoginStatus() method:

FB.getLoginStatus(function(response) {
	(response.session) ? showAccountInfo(): showLoginButton(); 
	FB.Event.subscribe('auth.statusChange', function() { // do something when auth status changes }); 
});

If the user is not logged in or has not provided the required permissions to your application, display the login button.

<img style="cursor: pointer;" 
onclick="FB.login( function(response) {yourObject.onStatus(response)},{ perms: 'email,publish_stream,offline_access,user_checkins,friends_birthday' })"
src="https://s-static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif"/>

The image, when clicked, calls the onStatus() method. “yourObject” assumes you are writing Object oriented JavaScript and the object is available in the namespace.

The permissions requested above are: email,publish_stream,offline_access,user_checkins,friends_birthday. You may want less, more or just the default information facebook makes available about every user. More information on permissions is available here: https://developers.facebook.com/tools/explorer

Thats it! The steps to have a user login and provide the required permissions to your application using the Facebook Graph API using JavaScript.

One of the things with using event listeners in JavaScript is that it causes memory leaks. This causes the website performance to slow down after a while. A pretty good description of how and why these memory leaks happen is explained here.

In Dojo, attaching events to an element are done as below:

dojo.connect(dojo.byId('elementId'), 'onclick'/*or other events*/, scope/*context*/, function(event) {
   //do something when the event happens.
});

Eugene Lazutkin’s solution here on StackOverflow is perfect in my opinion. I’ve started using it in all the Dijit widgets I’ve been writing. I put this in the destroy() method of the widget.

dojo.forEach(handles, dojo.disconnect);

I’ve noticed a lot of developers are unsure of how the box model concept works with respect to how rectangles are created for elements laid out on the DOM tree. Although this document explains it pretty well, I built a small example which I feel also demonstrates the core concept reasonably well.

http://jsfiddle.net/thxzc/1/

4 main concepts to properly understand the box model:

  1. Content: The actual content area with a width and height specified to it.
  2. Padding: Clears space inside the rectangle created for the content rectangle above. This padding also assumes he background color of the content area.
  3. Margin: Clears space OUTSIDE the rectangle created for the content rectangle above.
  4. Border: The border wraps around the content area/rectangle + the padding. It may or may not have its own color.

The actual size of the node includes the padding and the border. So if the width of a node is 200px, and it has a 10px padding and 1px border around it. Its real width is 222px(width + paddingLeft + paddingRight + borderLeft + borderRight).

Execute the example again and you will see how the height and width of the content area are computed: http://jsfiddle.net/thxzc/1/

Removing duplicates from a JavaScript array is an often encountered problem but after searching around, I have found very few good solutions to this. I wrote a small program but I realized that my solution had a O(n2) complexity. So I asked on twitter if someone knew of a better solution:

My friend pointed out that I can use a map. Since a JavaScript object is essentially a map. I came up with:

var arr = [
    { name: "a", age: 24},
    { name: "b", age: 25},
    { name: "a", age: 24},
    { name: "b", age: 25}
];

var newarr = [];
var unique = {};

dojo.forEach(arr, function(item) {
    if (!unique[item.age]) {
        newarr.push(item);
        unique[item.age] = item;
    }
});

console.log(dojo.toJson(newarr)); //prints [{"name":"a","age":24},{"name":"b","age":25}]

Here’s a JsFiddle link for the above code: http://jsfiddle.net/k6v3R/1/

I’m sure there are better solutions out there, but the complexity for the above code is O(n) although I’m thinking I don’t need to use both an object and an array to filter unique items.

Follow

Get every new post delivered to your Inbox.

Join 28 other followers