HTML5 Custom Data Attributes (data-*)

3:32:00 PM 0 Comments

Have you ever found yourself using element class names or rel attributes to store arbitrary snippets of metadata for the sole purpose of making your JavaScript simpler? If you have, then I have some exciting news for you! If you haven't and you're thinking, Wow, that's a great idea! I implore you to rid your mind of that thought immediately and continue reading.
Thanks to HTML5, we now have the ability to embed custom data attributes on all HTML elements. These new custom data attributes consist of two parts:
Attribute Name
The data attribute name must be at least one character long and must be prefixed with 'data-'. It should not contain any uppercase letters.
Attribute Value
The attribute value can be any string.
Using this syntax, we can add application data to our markup as shown below:
    id="vegetable-seeds">  
  • data-spacing="10cm" data-sowing-time="March to June">Carrots
  •  
  • data-spacing="30cm" data-sowing-time="February to March">Celery
  •  
  • data-spacing="3cm" data-sowing-time="March to September">Radishes
We can now use this stored data in our site’s JavaScript to create a richer, more engaging user experience. Imagine that when a user clicks on a vegetable a new layer opens up in the browser displaying the additional seed spacing and sowing instructions. Thanks to the data-attributes we’ve added to our 
  •  elements, we can now display this information instantly without having to worry about making any Ajax calls and without having to make any server-side database queries.
    Prefixing the custom attributes with data- ensures that they will be completely ignored by the user agent. As far as the browser and indeed the website’s end user are concerned, this data does not exist.
    The spec says (emphasis ours):
    Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
    These attributes are not intended for use by software that is independent of the site that uses the attributes.
    Every HTML element may have any number of custom data attributes specified, with any value.
    W3C Specification

    How can I use data attributes?

    As custom data attributes are valid HTML5, they can be used in any browser that supports HTML5 doctypes. Thankfully, this is pretty much all of them. In addition to aiding backwards compatibility, this also ensures that custom data attributes will remain a scalable, cross-platform solution well into the future.
    Now that we have a broad understanding of what data attributes are, let's take a look at how they can be used:
    • To store the initial height or opacity of an element which might be required in later JavaScript animation calculations
    • To store parameters for a Flash movie that’s loaded via JavaScript
    • To store custom web analytics tagging data as demonstrated by Jason Karns
    • To store data about the health, ammo, or lives of an element in a JavaScript game
    • To power accessible JavaScript  subtitles as demonstrated byBruce Lawson

    What shouldn’t I use data attributes for?

    Although flexible, data attributes aren’t an appropriate solution for all problems.
    • Data attributes should not be used if there is a existing attribute or element which is more appropriate for storing your data. For example, date/time data should probably be presented semantically in a time element instead rather than stored in custom data attributes.
    • Custom data attributes are not intended to compete with microformats. It is clearly stated in the spec that the data is not intended to be publicly usable. External software should not interact with it. Marking up contact details or event details using custom data attributes would be wrong, unless of course it is only intended to be used by your own internal scripts.
    • The presence/absence of a particular data attribute should not be used as a CSS hook for any styling. Doing so would suggest that the data you are storing is of immediate importance to the user and should be marked up in a more semantic and accessible manner.

    Using data- attributes with JavaScript

    Now that we understand what custom data- attributes are and when we can use them, we should probably take a look at how we can interact with them using JavaScript.
    If we wanted to retrieve or update these attributes using existing, native JavaScript, then we can do so using the getAttribute andsetAttribute methods as shown below:
    id='strawberry-plant' data-fruit='12'>
    This method will work in all modern browsers, but it is not how data-attributes are intended to be used. The second (new and improved) way to achieve the same thing is by accessing an element’s datasetproperty. This dataset property — part of the new HTML5 JavaScript APIs — will return a DOMStringMap object of all the selected element's data- attributes. When using this approach, rather than using the full attribute name, you can ditch the data- prefix and refer to the custom data directly using the name you have assigned to it. Data attribute names which contain hyphens will be stripped of their hyphens and converted to CamelCase.
    id='sunflower' data-leaves='47' data-plant-height='2.4m'>
    If, at some point in your script, a specific data- attribute becomes redundant and is no longer needed, it is also possible to completely remove that attribute from the DOM element by setting it to a value ofnull.
    plant.dataset.leaves = null; // Caterpillars attack!
    Unfortunately, the new dataset property has not yet been implemented in any browser, so in the meantime it’s best to usegetAttribute and setAttribute as demonstrated earlier.
    While developing your application, you may find it useful to be able to select elements based on the presence of — or indeed the specific values of — their custom data- attributes. This can be achieved quickly and easily using querySelectorAll as shown below:
    // Select all elements with a 'data-flowering' attribute
    document.querySelectorAll('[data-flowering]');
    // Select all elements with red leaves
    document.querySelectorAll('[data-foliage-colour="red"]');

    A word of warning

    As data attributes become more widely used, the potential for clashes in naming conventions becomes much greater. If you use an unimaginative attribute name such as data-height, then it is likely you will eventually come across a library or plugin that uses the same attribute name. Multiple scripts getting and setting a common data-attribute will probably cause chaos. In order to avoid this, I encourage people to choose a standard string (perhaps the site/plugin name) to prefix all their data- attributes — e.g. data-html5doctor-height ordata-my-plugin-height.

    Summary

    Custom data- attributes are a great way to simplify the storage of application data in your web pages. Although you can’t utilise the new JavaScript APIs just yet, you can enjoy great success usinggetAttribute and setAttribute safe in the knowledge that they will work in all major browsers.

    Homework

    If you’re super keen to have a play with the new dataset property but disappointed that it hasn’t been implemented, fear not!, for there is a light at the end of the tunnel. You might be interested in looking at Dr Remy’s experimental code, which partially enables the datasetfunctionality in some browsers by editing the Element.prototype.
    The code supports the retrieval of data- attributes in the latest versions of Firefox, Safari, Opera, and Chrome, but sadly will not work in any version of IE (since IE does not expose the Element object). This code also partially supports the setting of data attributes, but it will only store the new attribute values within the JavaScript and will not update the DOM element as a full, native implementation of thedataset property would. Although this code is mainly a proof of concept, it may be useful for mobile application or intranet development in closed environments where cross-browser (IE) compatibility is not an issue.

    ss: Display Linux TCP / UDP Network and Socket Information

    7:42:00 PM 0 Comments

    he ss command is used to show socket statistics. It can display stats for PACKET sockets, TCP sockets, UDP sockets, DCCP sockets, RAW sockets, Unix domain sockets, and much more. It allows showing information similar to netstat command. It can display more TCP and state information than other tools. It is a new, incredibly useful and faster (as compare to netstat) tool for tracking TCP connections and sockets. SS can provide information about:
    • All TCP sockets.
    • All UDP sockets.
    • All established ssh / ftp / http / https connections.
    • All local processes connected to X server.
    • Filtering by state (such as connected, synchronized, SYN-RECV, SYN-SENT,TIME-WAIT), addresses and ports.
    • All the tcp sockets in state FIN-WAIT-1 and much more.

    Most Linux distributions are shipped with ss and many monitoring tools. Being familiar with this tool helps enhance your understand of what's going on in the system sockets and helps you find the possible causes of a performance problem.

    Task: Display Sockets Summary

    List currently established, closed, orphaned and waiting TCP sockets, enter:
    # ss -s
    Sample Output:
    Total: 734 (kernel 904)
    TCP:   1415 (estab 112, closed 1259, orphaned 11, synrecv 0, timewait 1258/0), ports 566
    Transport Total     IP        IPv6
    *   904       -         -
    RAW   0         0         0
    UDP   15        12        3
    TCP   156       134       22
    INET   171       146       25
    FRAG   0         0         0  

    Task: Display All Open Network Ports

    # ss -l
    Sample Output:
    ss -l
    Recv-Q Send-Q                                                  Local Address:Port                                                      Peer Address:Port
    0      0                                                           127.0.0.1:smux                                                                 *:*
    0      0                                                           127.0.0.1:10024                                                                *:*
    0      0                                                           127.0.0.1:10025                                                                *:*
    0      0                                                                   *:3306                                                                 *:*
    0      0                                                                   *:http                                                                 *:*
    0      0                                                                   *:4949                                                                 *:*
    0      0                                                                   *:domain                                                               *:*
    0      0                                                                   *:ssh                                                                  *:*
    0      0                                                                   *:smtp                                                                 *:*
    0      0                                                           127.0.0.1:rndc                                                                 *:*
    0      0                                                           127.0.0.1:6010                                                                 *:*
    0      0                                                            *:https                                                                *:*
    0      0                                                                  :::34571                                                               :::*
    0      0                                                                  :::34572                                                               :::*
    0      0                                                                  :::34573                                                               :::*
    0      0                                                                 ::1:rndc                                                                :::*       
    Type the following to see process named using open socket:
    # ss -pl
    Find out who is responsible for opening socket / port # 4949:
    # ss -lp | grep 4949
    Sample output:
    0      0                            *:4949                          *:*        users:(("munin-node",3772,5))
    munin-node (PID # 3772) is responsible for opening port # 4949. You can get more information about this process (like memory used, users, current working directory and so on) visiting /proc/3772 directory:
    # cd /proc/3772
    # ls -l

    Task: Display All TCP Sockets

    # ss -t -a

    Task: Display All UDP Sockets

    # ss -u -a

    Task: Display All Established SMTP Connections

    # ss -o state established '( dport = :smtp or sport = :smtp )'

    Task: Display All Established HTTP Connections

    # ss -o state established '( dport = :http or sport = :http )'

    Task: Find All Local Processes Connected To X Server

    # ss -x src /tmp/.X11-unix/*

    Task: List All The Tcp Sockets in State FIN-WAIT-1

    List all the TCP sockets in state -FIN-WAIT-1 for our httpd to network 202.54.1/24 and look at their timers:
    # ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 202.54.1/24

    How Do I Filter Sockets Using TCP States?

    The syntax is as follows:
     
    ## tcp ipv4 ##
    ss -4 state FILTER-NAME-HERE
     
    ## tcp ipv6 ##
    ss -6 state FILTER-NAME-HERE
     
    Where FILTER-NAME-HERE can be any one of the following,
    1. established
    2. syn-sent
    3. syn-recv
    4. fin-wait-1
    5. fin-wait-2
    6. time-wait
    7. closed
    8. close-wait
    9. last-ack
    10. listen
    11. closing
    12. all : All of the above states
    13. connected : All the states except for listen and closed
    14. synchronized : All the connected states except for syn-sent
    15. bucket : Show states, which are maintained as minisockets, i.e. time-wait and syn-recv.
    16. big : Opposite to bucket state.

    Examples

    Type the following command to see closing sockets:
     
    ss -4 state closing
     
    Recv-Q Send-Q                                                  Local Address:Port                                                      Peer Address:Port
    1      11094                                                  75.126.153.214:http                                                      175.44.24.85:4669
    

    How Do I Matches Remote Address And Port Numbers?

    Use the following syntax:
     
    ss dst ADDRESS_PATTERN
     
    ## Show all ports connected from remote 192.168.1.5##
    ss dst 192.168.1.5
     
    ## show all ports connected from remote 192.168.1.5:http port## 
    ss dst 192.168.1.5:http
    ss dst 192.168.1.5:smtp
    ss dst 192.168.1.5:443
     
    Find out connection made by remote 123.1.2.100:http to our local virtual servers:
    # ss dst 123.1.2.100:http
    Sample outputs:
    State      Recv-Q Send-Q                                             Local Address:Port                                                 Peer Address:Port
    ESTAB      0      0                                                 75.126.153.206:http                                               123.1.2.100:35710
    ESTAB      0      0                                                 75.126.153.206:http                                               123.1.2.100:35758
    

    How Do I Matches Local Address And Port Numbers?

     
    ss src ADDRESS_PATTERN
    ### find out all ips connected to nixcraft.com ip address 75.126.153.214 ###
    ## Show all ports connected to local 75.126.153.214##
    ss src 75.126.153.214
     
    ## http (80) port only ##
    ss src 75.126.153.214:http
    ss src 75.126.153.214:80
     
    ## smtp (25) port only ##
    ss src 75.126.153.214:smtp
    ss src 75.126.153.214:25
     
     
     

    How Do I Compare Local and/or Remote Port To A Number?

    Use the following syntax:
     
    ## Compares remote port to a number ##
    ss dport OP PORT
     
    ## Compares local port to a number ##
    sport OP PORT
     
    Where OP can be one of the following:
    1. <= or le : Less than or equal to port
    2. >= or ge : Greater than or equal to port
    3. == or eq : Equal to port
    4. != or ne : Not equal to port
    5. < or gt : Less than to port
    6. > or lt : Greater than to port
    7. Note: le, gt, eq, ne etc. are use in unix shell and are accepted as well.

    Examples

     
    ###################################################################################
    ### Do not forget to escape special characters when typing them in command line ###
    ###################################################################################
     
    ss  sport = :http
    ss  dport = :http
    ss  dport \> :1024
    ss  sport \> :1024
    ss sport \< :32000
    ss  sport eq :22
    ss  dport != :22
    ss  state connected sport = :http
    ss \( sport = :http or sport = :https \)
    ss -o state fin-wait-1 \( sport = :http or sport = :https \) dst 192.168.1/24
     

    ss vs netstat Speed

    Use the time command to run both programs and summarize system resource usage. Type the netstat command as follows:
    # time netstat -at
    Sample outputs:
    real 2m52.254s
    user 0m0.178s
    sys 0m0.170s
    Now, try the ss command:
    # time
    Sample outputs:
    real 2m11.102s
    user 0m0.124s
    sys 0m0.068s
    
    Note: Both outputs are taken from reverse proxy acceleration server running on RHEL 6.x amd64.

    Recommended readings: