{"id":1168,"date":"2012-11-19T12:04:19","date_gmt":"2012-11-19T11:04:19","guid":{"rendered":"http:\/\/blog.kodono.info\/wordpress\/?p=1168"},"modified":"2013-03-18T16:22:36","modified_gmt":"2013-03-18T15:22:36","slug":"javascript-apis-youve-never-heard-of-and-some-you-have","status":"publish","type":"post","link":"https:\/\/blog.kodono.info\/wordpress\/2012\/11\/19\/javascript-apis-youve-never-heard-of-and-some-you-have\/","title":{"rendered":"JavaScript APIs you&#8217;ve never heard of (And some you have)"},"content":{"rendered":"<p>From <a href=\"http:\/\/www.youtube.com\/watch?v=TdDwFOTB3p8\">this video<\/a> I&#8217;ve discovered several JS API I didn&#8217;t know. Let&#8217;s list them:<\/p>\n<p>1) Use <code>children<\/code> instead of <code>childNodes<\/code> to list the children nodes of a DOM element:<\/p>\n<pre class=\"brush: html\">\r\n&lt;ul>\r\n  &lt;li>Hello&lt;\/li>\r\n  &lt;li>world&lt;\/li>\r\n  &lt;li>!&lt;\/li>\r\n&lt;\/ul>\r\n<\/pre>\n<pre class=\"brush: javascript\">\r\n&lt;script>\r\ndocument.getElementById('test').childNodes.length; \/\/ 7 -> because it also returns the text nodes\r\ndocument.getElementById('test').children.length; \/\/ 3\r\n&lt;\/script>\r\n<\/pre>\n<p><strong>Support<\/strong>: all browsers, but from IE6 to IE8 it will also return the comments nodes <code>&lt;!-- --><\/code><\/p>\n<p>2) Use <code>nextElementSibling \/ previousElementSibling \/ firstElementChild \/ lastElementChild<\/code> instead of <code>nextSibling \/ previousSibling \/ firstChild \/ lastChild<\/code>, because the second one will return the text nodes, but no the first one:<\/p>\n<pre class=\"brush: javascript\">\r\n&lt;script>\r\ndocument.getElementById('test').firstChild; \/\/ #textNode\r\ndocument.getElementById('test').firstElementChild; \/\/ LI\r\n&lt;\/script>\r\n<\/pre>\n<p><strong>Support<\/strong>: IE9+, FF3.5+, Chrome.<\/p>\n<p>3) Use <code>contains()<\/code> to indicates whether a node is a descendent of a given node:<\/p>\n<pre class=\"brush: html\">\r\n&lt;body>\r\n&lt;ul>\r\n  &lt;li>\r\n  &lt;li id=\"test\">\r\n  &lt;li>\r\n&lt;\/ul>\r\n&lt;\/body>\r\n<\/pre>\n<pre class=\"brush: javascript\">\r\n&lt;script>\r\ndocument.body.contains(document.getElementById('test')); \/\/ TRUE\r\n&lt;\/script>\r\n<\/pre>\n<p><strong>Support<\/strong>: all browsers.<\/p>\n<p>4) Insert an HTML element with <code>insertAdjacentHTML<\/code> (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/DOM\/element.insertAdjacentHTML\">see on MDN<\/a>):<\/p>\n<pre class=\"brush: html\">\r\n&lt;div id=\"one\">one&lt;\/div>\r\n<\/pre>\n<pre class=\"brush: javascript\">\r\n&lt;script>\r\n\/\/ the first param of insertAdjacentHTML can be :\r\n\/\/ &lt;!-- beforebegin -->&lt;div id=\"one\">&lt;!-- afterbegin -->one&lt;!--beforeend -->&lt;\/div>&lt;!-- afterend -->\r\ndocument.getElementById('one').insertAdjacentHTML('afterend', '<div id=\"two\">two<\/div>');\r\n\r\n\/\/ At this point, the new structure is:\r\n\/\/ <div id=\"one\">one<\/div><div id=\"two\">two<\/div>\r\n&lt;\/script>\r\n<\/pre>\n<p><strong>Support<\/strong>: all browsers.<\/p>\n<p>5) If you want to replace a node you can either use <code>replaceChild<\/code> or <code>outerHTML<\/code>. See <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/DOM\/element.outerHTML\">outerHTML on MDN<\/a>.<\/p>\n<p><strong>Support<\/strong>: all browsers.<\/p>\n<p>6) <code>Input.setSelection()<\/code> sets the start and end positions of the current text selection in an &lt;input> element. That could be useful to put the caret in a particular place (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/DOM\/Input.setSelectionRange\">see on MDN<\/a>):<\/p>\n<pre class=\"brush: javascript\">\r\nvar textbox=document.getElementById('my-input');\r\ntextbox.setSelectionRange(textbox.value.length,textbox.value.length); \/\/ the caret will be at the end of the input text\r\n<\/pre>\n<p><strong>Support<\/strong>: All browsers, except for IE (only from IE9).<\/p>\n<p>7) The <code>document.activeElement<\/code> returns the currently focused element (see <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/DOM\/document.activeElement\">details on MDN<\/a>):<\/p>\n<pre class:\"brush: javascript\">\r\ndocument.getElementById('my-input').focus();\r\ndocument.activeElement; \/\/ #my-input\r\n<\/pre>\n<p><strong>Support<\/strong>: all browsers.<\/p>\n<p>8) The <code>new FormData<\/code> is part of the XMLHttpRequest Level 2 and permits to easily construct a set of key\/value pairs representing form fields and their values and then send them with the <code>send()<\/code> command (see <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/DOM\/XMLHttpRequest\/FormData\">more on MDN<\/a>):<\/p>\n<pre class=\"brush: javascript\">\r\nvar data=new FormData();\r\ndata.append(\"name\",\"Paul\");\r\ndata.append(\"age\",15);\r\nvar xhr = new XMLHttpRequest();\r\nxhr.open(\"post\", \"\/submit\", true);\r\nxhr.send(data);\r\n<\/pre>\n<p><strong>Support<\/strong>: it&#8217;s quite well supported, except from IE from version 10 only<\/p>\n<p>Note: <a href=\"http:\/\/www.youtube.com\/watch?v=TdDwFOTB3p8\">the video<\/a> gives more functions regarding the XMLHttpRequest Level 2<\/p>\n<p>9) <code>Element.matchesSelector()<\/code> permits to test a CSS selector over an element. It&#8217;s prefixed so we&#8217;ll create a function:<\/p>\n<pre class=\"brush: html\">\r\n&lt;div>&lt;span class=\"title\" id=\"test\">Hello world!&lt;\/span>&lt;\/div>\r\n<\/pre>\n<pre class=\"brush: javascript\">\r\nif (!Element.prototype.matchesSelector) {\r\n  Element.prototype.matchesSelector = function(css) {\r\n    if (this.webkitMatchesSelector) return this.webkitMatchesSelector(css)\r\n    if (this.mozMatchesSelector) return this.mozMatchesSelector(css)\r\n    if (this.msMatchesSelector) return this.msMatchesSelector(css)\r\n    if (this.oMatchesSelector) return this.oMatchesSelector(css)\r\n  } \r\n}\r\n\r\nvar span=document.getElementById('test');\r\nspan.matchesSelector('#test'); \/\/ true\r\nspan.matchesSelector('.title'); \/\/ true\r\nspan.matchesSelector('div > span'); \/\/ true\r\n<\/pre>\n<p><strong>Support<\/strong>: all browsers, except for IE starting from IE9.<\/p>\n<p>10) <code>getBoundingClientRect<\/code> permits to know the size and the position of an element in the viewport:<\/p>\n<pre class=\"brush: javascript\">\r\nvar div=document.getElementById('test');\r\nvar rect=div.getBoundingClientRect();\r\n\/\/ in pixels, relative to the viewport\r\nrect.left;\r\nrect.top;\r\nrect.right; \/\/ relative to left\r\nrect.bottom; \/\/ relative to top\r\nrect.width;\r\nrect.height;\r\n<\/pre>\n<p><strong>Support<\/strong>: all browsers, however with IE&lt;8 there is a bug that adds 2 to the different positions.<\/p>\n<p>11) <code>document.elementFromPoint(x,y)<\/code> returns the element that is in the (x,y) coordinates. For example, this is useful to know over which element the mouse is.<\/p>\n<p><strong>Support<\/strong>: all browsers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From this video I&#8217;ve discovered several JS API I didn&#8217;t know. Let&#8217;s list them: 1) Use children instead of childNodes to list the children nodes of a DOM element: &lt;ul> &lt;li>Hello&lt;\/li> &lt;li>world&lt;\/li> &lt;li>!&lt;\/li> &lt;\/ul> &lt;script> document.getElementById(&#8216;test&#8217;).childNodes.length; \/\/ 7 -> because it also returns the text nodes document.getElementById(&#8216;test&#8217;).children.length; \/\/ 3 &lt;\/script> Support: all browsers, but from [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","hide_page_title":"","footnotes":""},"categories":[13,33],"tags":[24,152,158],"class_list":["post-1168","post","type-post","status-publish","format-standard","hentry","category-niveau-intermediaire","category-programmation","tag-javascript","tag-niveau-intermediaire","tag-programmation"],"_links":{"self":[{"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/posts\/1168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/comments?post=1168"}],"version-history":[{"count":14,"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/posts\/1168\/revisions"}],"predecessor-version":[{"id":1201,"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/posts\/1168\/revisions\/1201"}],"wp:attachment":[{"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/media?parent=1168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/categories?post=1168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.kodono.info\/wordpress\/wp-json\/wp\/v2\/tags?post=1168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}