{"id":1309,"date":"2016-12-22T14:16:36","date_gmt":"2016-12-22T14:16:36","guid":{"rendered":"https:\/\/solutionstreet.com\/blog\/?p=1309"},"modified":"2016-12-22T14:16:36","modified_gmt":"2016-12-22T14:16:36","slug":"faster-unobtrusive-javascript-with-data-attributes","status":"publish","type":"post","link":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/","title":{"rendered":"Faster Unobtrusive JavaScript with Data Attributes"},"content":{"rendered":"<p><a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1341\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png\" alt=\"decembertitle\" width=\"810\" height=\"354\" srcset=\"https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png 300w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-768x335.png 768w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle.png 822w\" sizes=\"auto, (max-width: 810px) 100vw, 810px\" \/><\/a><\/p>\n<p>Many developers have jumped on the bandwagon of full JavaScript user interfaces and moved all presentation logic from the server side to a client-side framework like React.js or Angular.js. While this may sound like fun, there are millions of applications out there in the world that use server-side rendering of HTML and JavaScript. This article is for these folks and how they can use data attributes to make their code a little cleaner.<\/p>\n<p>&nbsp;<\/p>\n<p>For years, developers have used JavaScript to enhance their web pages and make them more usable. In many server-side scripting frameworks such as .jsp, .asp, Ruby on Rails(.erb), Python\/Django, and PHP, developers use these scripting frameworks to inject inline dynamic JavaScript into the pages. This JavaScript can be customized for the use case while the page is being built, making it easy to build custom logic on the fly. This can make your pages faster and more interactive without having to make Ajax calls back to the server to gather and format data.<\/p>\n<p>&nbsp;<\/p>\n<p>Let&#8217;s take the use case of a \u201cWatch Registration System\u201d, where we want users who have recently purchased a watch to be able to register their watch. Some watches the company sells have serial numbers and others do not, so we want to make our \u201cserial number\u201d field disappear when we choose a model that does not have a serial number, and make it appear when we choose a model with a serial number. In our use case we have three watch models: \u201cAnthem\u201d; \u201cAgent\u201d; and \u201cMission\u201d. Only the Mission model has a serial number, so when we choose Mission, we should show the serial number field like in Figure A.<\/p>\n<p><em>Figure A<\/em><br \/>\n<a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/image01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-984 size-full\" style=\"border: 2px solid #021a40;\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/image01.png\" alt=\"image1\" width=\"191\" height=\"96\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>If we don\u2019t choose any model or we choose one of the other two models, we want to hide the serial number field as in Figure B.<\/p>\n<p><em>Figure B<\/em><br \/>\n<a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/image00.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-984 size-full\" style=\"border: 2px solid #021a40;\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/image00.png\" alt=\"image1\" width=\"206\" height=\"99\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>When using a server-side scripting framework, I could easily generate a JavaScript key\/value pair with model IDs and serial number true\/false. This way if someone updated the reference data and changed one of the models to have a serial number or not, the JavaScript will be generated correctly.<\/p>\n<p>&nbsp;<\/p>\n<p>In Ruby on Rails we could leverage server side .erb to <strong>generate<\/strong> an inline JavaScript helper using some code like this:<\/p>\n<p>&nbsp;<\/p>\n<p>Example Ruby on Rails code to generated JavaScript:<br \/>\n<strong>File:<\/strong> _form.erb.html<\/p>\n<pre lang=\"javascript\" line=\"1\"><script>\nfunction showHideSerialCheck(modelId)\n{\n    var model_serial_hash = {};\n    <% @registerable_models.each{|model| %>\n   \t model_serial_hash[<%=model.id%>] = <%=model.serial_number_available%>\n    <% } %>\n    if(model_serial_hash[modelId] == true)\n  \t{\n    \t$('#watch_registration_serial_number').show();\n  \t}\n  \telse\n  \t{\n    \t$('#watch_registration_serial_number').hide();\n  \t}\n}\n\n\n $(\"#watch_registration_model_id\").on('change', function() {\n    showHideSerialCheck(this)\n  });\n\n\n<\/script>\n\n<%= form_for(@watch_registration) do |f| %>\n<\/br>\n<%= f.select(:model_id, @registerable_models.collect {|p| [ p.name, p.id] }, {include_blank: t(\"generic.model\")}) %>\n<\/br>\n<%= f.text_field :serial_number, :placeholder => t(\"registration_center.serial_number\"), style: 'display:none' %>\n<% end %>\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Since this code is in a server-side template, it generates the following HTML code. Notice the JavaScript object key\/value pairs populated in a variable.<\/p>\n<p>&nbsp;<\/p>\n<p>Example Ruby on Rails generated HTML and JavaScript:<br \/>\n<strong>File:<\/strong> generated new\/show.html file<\/p>\n<pre lang=\"javascript\" line=\"1\"><script>\n\nfunction showHideSerialCheck(modelId)\n{\n    var model_serial_hash = {};\n    model_serial_hash[42] = false\n    model_serial_hash[242] = false\n    model_serial_hash[2512] = true\n    if(model_serial_hash[modelId] == true)\n    {\n        $('#watch_registration_serial_number').show();\n    }\n    else\n    {\n        $('#watch_registration_serial_number').hide();\n    } \n}\n\n$(\"#watch_registration_model_id\").on('change', function() {\n    showHideSerialCheck(this)\n});\n\n<\/script>\n\n<form id=\"new_watch_registration\" class=\"new_watch_registration\" accept-charset=\"UTF-8\" action=\"\/watch_registrations?locale=en-US\" method=\"post\"><input name=\"utf8\" type=\"hidden\" value=\"\u2713\" \/> <input name=\"authenticity_token\" type=\"hidden\" value=\"xyz==\" \/><select id=\"watch_registration_model_id\" name=\"watch_registration[model_id]\">\n<option value=\"\">Model<\/option>\n<option value=\"42\">38-20 Chrono<\/option>\n<option value=\"242\">Agent<\/option>\n<option value=\"2512\">Mission<\/option>\n<\/select><input id=\"watch_registration_serial_number\" style=\"display: none;\" name=\"watch_registration[serial_number]\" type=\"text\" placeholder=\"Watch Serial Number\" \/><\/form>&nbsp;\n\n<\/pre>\n<p>This works, the code is simple and easy to write and the page is very fast, and no Ajax calls are needed to draw the page or figure out what to do on the drop down select.<\/p>\n<p>&nbsp;<\/p>\n<p>The problem is it is no longer considered ideal to have inline JavaScript in the page. This is considered bad form and it is better for many reasons to put the JavaScript into its own file and use unobtrusive JavaScript to make this happen. To do this, we no longer have access to our server-side data, and on first glance this would make our problem above hard to do.<\/p>\n<p>&nbsp;<\/p>\n<p>Data attributes can help us solve this problem in an elegant way. HTML5 is designed with extensibility in mind for data that should be associated with a particular element but need not have any defined meaning. data-* attributes allow us to store extra information on standard, semantic HTML elements without other hacks such as adding non-standard extra properties on the DOM.<\/p>\n<p>&nbsp;<\/p>\n<p>With data attributes, we can change our Ruby code slightly to generate each element of our select drop down with an extra attribute called \u201cdata-serial\u201d; in this case just adding a \u201ctrue\u201d or \u201cfalse\u201d value if the model has a serial number or not.<\/p>\n<p>&nbsp;<\/p>\n<p>Example Ruby on Rails code with data attributes (note no generated inline JavaScript):<br \/>\n<strong>File:<\/strong> _form.erb.html<\/p>\n<pre lang=\"javascript\" line=\"1\">\n<%= form_for(@watch_registration) do |f| %>\n<\/br>\n<%= f.select(:model_id, @registerable_models.collect {|p| [ p.name, p.id, { 'data-serial' => p.serial_number_available } ] }, {include_blank: t(\"generic.model\")}) %>\n<\/br>\n<%= f.text_field :serial_number, :placeholder => t(\"registration_center.serial_number\"), style: 'display:none' %>\n<% end %>\n<\/pre>\n<p>This generates HTML that looks like:<\/p>\n<pre lang=\"javascript\" line=\"1\">\n<div class=\"group-inputs\"><select id=\"watch_registration_model_id\" name=\"watch_registration[model_id]\">\n<option value=\"\">Model<\/option>\n<option value=\"42\" data-serial=\"false\">Anthem<\/option>\n<option value=\"242\" data-serial=\"false\">Agent<\/option>\n<option value=\"2512\" data-serial=\"true\">Mission<\/option>\n<\/select><\/div>\n\n<input id=\"watch_registration_serial_number\" style=\"display: none;\" name=\"watch_registration[serial_number]\" type=\"text\" placeholder=\"Watch Serial Number\" \/>\n\n<\/pre>\n<p>Now we can put our JavaScript in a separate file and have it not know about any data. We just grab the element that was selected and check if its data attribute is true or false and show\/hide the element accordingly.<\/p>\n<p>&nbsp;<\/p>\n<p>Example JavaScript that leverages data attributes:<br \/>\n <strong>File:<\/strong> watch_registration.js<\/p>\n<pre lang=\"javascript\" line=\"1\">function showHideSerial(component)\n{\n  \tvar dataid = $(component).find(':selected').data('serial');\n  \tif (dataid == null || dataid == false)\n  \t{\n    \t    $('#watch_registration_serial_number').hide();\n  \t}\n  \telse\n  \t{\n    \t    $('#watch_registration_serial_number').show();\n  \t}\n \n}\n\n\n  $(\"#watch_registration_model_id\").on('change', function() {\n  \tshowHideSerial(this)\n  });\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Now we have the same working code and it does not rely on generating any JavaScript variables and the JavaScript does not need to be inline in the code nor rendered on the server side because no variables are injected. Previously I mentioned that there were several good reasons not to put your JavaScript inline. Let\u2019s discuss those now.<\/p>\n<p>&nbsp;<\/p>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Web_Standards_Project\">Web Standards Project<\/a> describes four benefits of unobtrusive DOM scripting in their <em>JavaScript Manifesto<\/em>.<\/p>\n<p>&nbsp;<\/p>\n<ol>\n<li><strong>Usability:<\/strong> An unobtrusive DOM script does not draw the attention of the user &#8211; visitors use it without thinking about it.<\/li>\n<p>&nbsp;<\/p>\n<li><strong>Graceful degradation:<\/strong> Unobtrusive DOM scripts never generate error messages, in any browser, even when they fail. If features cannot be presented properly, they silently disappear.<\/li>\n<p>&nbsp;<\/p>\n<li><strong>Accessibility:<\/strong> If any script fails, the page still delivers its core functions and information via the markup, stylesheets, and\/or server-side scripting.<\/li>\n<p>&nbsp;<\/p>\n<li><strong>Separation:<\/strong> For the benefit of other and future web developers, all JavaScript code is maintained separately, without impacting other files of script, markup, or code.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>For me, #4 in the list above is huge. It allows you to more easily manage, package, and minify your JavaScript making your whole site use less bandwidth and perform better.<\/p>\n<p>&nbsp;<\/p>\n<p>Lastly, if you are using the Ruby on Rails framework or other framework that supports something like <a href=\"https:\/\/github.com\/turbolinks\/turbolinks\">TurboLinks<\/a> or <a href=\"https:\/\/github.com\/defunkt\/jquery-pjax\">PJax<\/a>, you will have to package your JavaScript into one file to make it work. TurboLinks and PJax can make your users\u2019 browser experience considerably faster.<\/p>\n<p>&nbsp;<\/p>\n<p>Hope these tips helped. Enjoy your JavaScript coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many developers have jumped on the bandwagon of full JavaScript user interfaces and moved all presentation logic from the server side to a client-side framework like React.js or Angular.js. While this may sound like fun, there are millions of applications out there in the world that use server-side rendering of HTML and JavaScript. This article [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1309","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Faster Unobtrusive JavaScript with Data Attributes - Solution Street Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Faster Unobtrusive JavaScript with Data Attributes - Solution Street Blog\" \/>\n<meta property=\"og:description\" content=\"Many developers have jumped on the bandwagon of full JavaScript user interfaces and moved all presentation logic from the server side to a client-side framework like React.js or Angular.js. While this may sound like fun, there are millions of applications out there in the world that use server-side rendering of HTML and JavaScript. This article [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/\" \/>\n<meta property=\"og:site_name\" content=\"Solution Street Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-12-22T14:16:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png\" \/>\n<meta name=\"author\" content=\"afrankel\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"afrankel\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/\"},\"author\":{\"name\":\"afrankel\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#\\\/schema\\\/person\\\/4918a8dfd726e6176a3b516b9f1fd00f\"},\"headline\":\"Faster Unobtrusive JavaScript with Data Attributes\",\"datePublished\":\"2016-12-22T14:16:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/\"},\"wordCount\":1001,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/12\\\/DecemberTitle-300x131.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/\",\"url\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/\",\"name\":\"Faster Unobtrusive JavaScript with Data Attributes - Solution Street Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/12\\\/DecemberTitle-300x131.png\",\"datePublished\":\"2016-12-22T14:16:36+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#\\\/schema\\\/person\\\/4918a8dfd726e6176a3b516b9f1fd00f\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#primaryimage\",\"url\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/12\\\/DecemberTitle-300x131.png\",\"contentUrl\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/12\\\/DecemberTitle-300x131.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2016\\\/12\\\/22\\\/faster-unobtrusive-javascript-with-data-attributes\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Faster Unobtrusive JavaScript with Data Attributes\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/\",\"name\":\"Solution Street Blog\",\"description\":\"Quality Software Engineering - Technology and Consulting Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#\\\/schema\\\/person\\\/4918a8dfd726e6176a3b516b9f1fd00f\",\"name\":\"afrankel\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/906488c05ad8322b055f0d85b5cee1f6f966ce8715b51d59df3f0ced8ae01b6b?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/906488c05ad8322b055f0d85b5cee1f6f966ce8715b51d59df3f0ced8ae01b6b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/906488c05ad8322b055f0d85b5cee1f6f966ce8715b51d59df3f0ced8ae01b6b?s=96&d=mm&r=g\",\"caption\":\"afrankel\"},\"url\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/author\\\/afrankel\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Faster Unobtrusive JavaScript with Data Attributes - Solution Street Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/","og_locale":"en_US","og_type":"article","og_title":"Faster Unobtrusive JavaScript with Data Attributes - Solution Street Blog","og_description":"Many developers have jumped on the bandwagon of full JavaScript user interfaces and moved all presentation logic from the server side to a client-side framework like React.js or Angular.js. While this may sound like fun, there are millions of applications out there in the world that use server-side rendering of HTML and JavaScript. This article [&hellip;]","og_url":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/","og_site_name":"Solution Street Blog","article_published_time":"2016-12-22T14:16:36+00:00","og_image":[{"url":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png","type":"","width":"","height":""}],"author":"afrankel","twitter_card":"summary_large_image","twitter_misc":{"Written by":"afrankel","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#article","isPartOf":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/"},"author":{"name":"afrankel","@id":"https:\/\/www.solutionstreet.com\/blog\/#\/schema\/person\/4918a8dfd726e6176a3b516b9f1fd00f"},"headline":"Faster Unobtrusive JavaScript with Data Attributes","datePublished":"2016-12-22T14:16:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/"},"wordCount":1001,"commentCount":0,"image":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#primaryimage"},"thumbnailUrl":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/","url":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/","name":"Faster Unobtrusive JavaScript with Data Attributes - Solution Street Blog","isPartOf":{"@id":"https:\/\/www.solutionstreet.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#primaryimage"},"image":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#primaryimage"},"thumbnailUrl":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png","datePublished":"2016-12-22T14:16:36+00:00","author":{"@id":"https:\/\/www.solutionstreet.com\/blog\/#\/schema\/person\/4918a8dfd726e6176a3b516b9f1fd00f"},"breadcrumb":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#primaryimage","url":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png","contentUrl":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2016\/12\/DecemberTitle-300x131.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.solutionstreet.com\/blog\/2016\/12\/22\/faster-unobtrusive-javascript-with-data-attributes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.solutionstreet.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Faster Unobtrusive JavaScript with Data Attributes"}]},{"@type":"WebSite","@id":"https:\/\/www.solutionstreet.com\/blog\/#website","url":"https:\/\/www.solutionstreet.com\/blog\/","name":"Solution Street Blog","description":"Quality Software Engineering - Technology and Consulting Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.solutionstreet.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.solutionstreet.com\/blog\/#\/schema\/person\/4918a8dfd726e6176a3b516b9f1fd00f","name":"afrankel","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/906488c05ad8322b055f0d85b5cee1f6f966ce8715b51d59df3f0ced8ae01b6b?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/906488c05ad8322b055f0d85b5cee1f6f966ce8715b51d59df3f0ced8ae01b6b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/906488c05ad8322b055f0d85b5cee1f6f966ce8715b51d59df3f0ced8ae01b6b?s=96&d=mm&r=g","caption":"afrankel"},"url":"https:\/\/www.solutionstreet.com\/blog\/author\/afrankel\/"}]}},"_links":{"self":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/posts\/1309","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/comments?post=1309"}],"version-history":[{"count":0,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/posts\/1309\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/media?parent=1309"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/categories?post=1309"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/tags?post=1309"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}