\r\nI use the DOMReady extension for Prototype's Event object, but you can use any loader you want. The Ajax.Responders.register part reruns the script after a drag-and-drop operation (or any Ajax operation really).\r\n\r\nDownload Scriptaculous and Prototype.\r\n\r\nvar FirstLast = {\r\n go: function(el) {\r\n el = $(el);\r\n\r\n // Whitespace nodes need to be cleaned to get the intended effect\r\n var children = Element.cleanWhitespace(el).childNodes;\r\n\r\n // Return if there are not any children\r\n if (0 == children.length) return\r\n \r\n if (1 == children.length) {\r\n // Cheap shortcut if there is only 1 child node\r\n children[0].addClassName(this._firstChildClassName);\r\n children[0].addClassName(this._lastChildClassName);\r\n } else {\r\n for (var i = 0; i < children.length; i++) {\r\n switch (i) {\r\n // First child\r\n case 0:\r\n children[i].addClassName(this._firstChildClassName);\r\n children[i].removeClassName(this._lastChildClassName);\r\n break;\r\n // Last child\r\n case children.length - 1:\r\n children[i].removeClassName(this._firstChildClassName);\r\n children[i].addClassName(this._lastChildClassName);\r\n break;\r\n // Every child other than the first or last\r\n default:\r\n children[i].removeClassName(this._firstChildClassName);\r\n children[i].removeClassName(this._lastChildClassName);\r\n break; // I know it is unnecessary\r\n }\r\n }\r\n }\r\n },\r\n // Pseudo Private methods and attributes\r\n _firstChildClassName: \"first\",\r\n _lastChildClassName: \"last\"\r\n};","bodyAsHTML":"
I know CSS has the :first-child and :last-child pseudo classes.  But :first-child is a part of CSS 2 and has poor browsers support and :last-child is a part of CSS 3 and that's not worth thinking about using yet.  The idea is sound though, so I worked up this JavaScript method of getting the same effect.\r\n\r\nOne advantage of doing this in JavaScript rather than using CSS is that the classes will change if you reorder the child nodes with more JavaScript.  In my case I'm using Scriptaculous sortables.  Or to be more specific, I'm using a Ruby on Rails helper method to make something sortable through Scriptaculous:\r\n<%= sortable_element 'image-list',\r\n    :constraint => false,\r\n    :url => { :action => 'sort', :issue_id => params[:issue_id] }\r\n-%>\r\n\r\nI've chosen to not make this script run unobtrusively.  Most of it can go into a file and be included in the header or added to your own common JavaScript include file.  To get it to run on a page you will need to include something like the below in each page.\r\n\r\nI use the DOMReady extension for Prototype's Event object, but you can use any loader you want.  The Ajax.Responders.register part reruns the script after a drag-and-drop operation (or any Ajax operation really).\r\n\r\nDownload Scriptaculous and Prototype.\r\n\r\nvar FirstLast = {\r\n    go: function(el) {\r\n        el = $(el);\r\n\r\n        // Whitespace nodes need to be cleaned to get the intended effect\r\n        var children = Element.cleanWhitespace(el).childNodes;\r\n\r\n        // Return if there are not any children\r\n        if (0 == children.length) return\r\n        \r\n        if (1 == children.length) {\r\n            // Cheap shortcut if there is only 1 child node\r\n            children[0].addClassName(this._firstChildClassName);\r\n            children[0].addClassName(this._lastChildClassName);\r\n        } else {\r\n            for (var i = 0; i < children.length; i++) {\r\n                switch (i) {\r\n                    // First child\r\n                    case 0:\r\n                        children[i].addClassName(this._firstChildClassName);\r\n                        children[i].removeClassName(this._lastChildClassName);\r\n                        break;\r\n                    // Last child\r\n                    case children.length - 1:\r\n                        children[i].removeClassName(this._firstChildClassName);\r\n                        children[i].addClassName(this._lastChildClassName);\r\n                        break;\r\n                    // Every child other than the first or last\r\n                    default:\r\n                        children[i].removeClassName(this._firstChildClassName);\r\n                        children[i].removeClassName(this._lastChildClassName);\r\n                        break;  // I know it is unnecessary\r\n                }\r\n            }\r\n        }\r\n    },\r\n    // Pseudo Private methods and attributes\r\n    _firstChildClassName: \"first\",\r\n    _lastChildClassName: \"last\"\r\n};
","author":{"id":1018055,"username":"Snippets_User","realname":null,"emailHash":"7c2a6e78db5bc42c725740ccc54d15b6","avatar":"https://secure.gravatar.com/avatar/7c2a6e78db5bc42c725740ccc54d15b6?d=identicon&r=PG","reputation":0},"activeRevisionId":991539,"revisionIds":[991539],"lastActiveUserId":1018055,"lastActiveDate":1159125392000,"parentId":null,"parentAuthor":null,"originalParentId":null,"childrenIds":[],"commentIds":[],"marked":true,"topics":[],"primaryContainerId":8,"containerIds":[],"plug":"firstlast-real-classes","wiki":false,"score":0,"depth":0},"enableThreadedComments":true,"contentType":"article"}],"loadedStyles":[["/lib/bootstrap/bootstrap.less","/lib/font-awesome/font-awesome.less","/lib/fontello/css/fontello.css","/lib/fontello/css/animation.css","/lib/angular-ui/select.css","/lib/ngDialog/css/ngDialog.css","/less/ngDialog-theme.less","/lib/bootstrap-switch/bootstrap-switch.css","/less/dzone20.less","/less/fonts.less","/less/directives.less","/lib/slick/slick.css","/lib/bootstrap-slider/bootstrap-slider.css","/less/layout.less","/widgets/article/content/article-content.less","/widgets/article/infoBar/widget.less","/widgets/components/slider/widget.less","/widgets/content/commentsSlider/widget.less","/widgets/header/blackBar/widget.less","/widgets/header/main/header-common.less","/widgets/header/main/widget.less","/widgets/sidebar/content/list/list.less","/widgets/sidebar/tapBar/sidebar-list.less","/widgets/sidebar/tapBar/widget.less","/widgets/users/UserHomeMiniProfile/widget.less"]],"loadedScripts":[["/lib/jquery/jquery.js","/lib/lodash/lodash.js","/lib/moment/moment.js","/scripts/utils.js","/lib/angular/angular.js","/lib/angular/angular-sanitize.js","/lib/local-storage/angular-local-storage.js","/lib/bootstrap/bootstrap.js","/lib/angular-ui/bootstrap.js","/lib/angular-ui/select.js","/lib/bootstrap-switch/bootstrap-switch.js","/lib/ngDialog/js/ngDialog.js","/lib/angular-moment/angular-moment.js","/scripts/app.js","/scripts/socket.js","/scripts/services.js","/scripts/ui-services.js","/scripts/directives.js","/scripts/filters.js","/lib/angular-touch/angular-touch.min.js","/lib/elastic/elastic.js","/lib/ng-file-upload/angular-file-upload-all.js","/lib/angular-deckgrid/angular-deckgrid.js","/scripts/dzone.js","/scripts/ads.js","/scripts/head.js","/scripts/links.js","/scripts/utilities/directives.js","/scripts/utilities/services.js","/scripts/utilities/image-editor.js","/lib/bootstrap-slider/bootstrap-slider.js","/lib/bootstrap-slider/directive.js","/lib/angular-draganddrop/draganddrop.js","/widgets/article/content/utils.js","/widgets/article/infoBar/services.js","/widgets/components/slider/service.js","/widgets/header/main/angulartics-ga.js","/widgets/header/main/angulartics.js","/widgets/header/main/resize.js","/widgets/sidebar/content/list/service.js","/widgets/sidebar/tapBar/directive.js","/widgets/sidebar/tapBar/service.js"]],"TH_CSRF":"-3951264811754379814","botInfo":[{"isRenderBot":false}],"request":[{"site":{"id":7,"title":"DZone: Programming & DevOps news, tutorials & tools","keywords":"programming, software development, devops, java, agile, web, iot, database, mobile, big data, cloud","description":"Programming, Web Development, and DevOps news, tutorials and tools for beginners to experts. Hundreds of free publications, over 1M members, totally free.","name":"DZone.com"},"dev":false,"cdn":["dz2cdn1.dzone.com","dz2cdn2.dzone.com","dz2cdn3.dzone.com","dz2cdn4.dzone.com"],"theme":"dz20","context":"","user":{"id":2500002,"authenticated":false,"name":"Anonymous","realName":null,"avatar":"https://secure.gravatar.com/avatar/?d=identicon&r=PG","profile":"/users/2500002/anon-user.html"}}],"portals":[[{"topic":8,"id":2,"shortTitle":"agile-methodology-training-tools-news","color":"red","name":"Agile","code":"agile","url":"/agile-methodology-training-tools-news"},{"topic":6129,"id":3,"shortTitle":"big-data-analytics-tutorials-tools-news","color":"green","name":"Big Data","code":"big-data","url":"/big-data-analytics-tutorials-tools-news"},{"topic":30,"id":4,"shortTitle":"cloud-computing-tutorials-tools-news","color":"orange","name":"Cloud","code":"cloud","url":"/cloud-computing-tutorials-tools-news"},{"topic":59,"id":5,"shortTitle":"database-sql-nosql-tutorials-tools-news","color":"purple","name":"Database","code":"database","url":"/database-sql-nosql-tutorials-tools-news"},{"topic":31,"id":6,"shortTitle":"devops-tutorials-tools-news","color":"yellow","name":"DevOps","code":"devops","url":"/devops-tutorials-tools-news"},{"topic":1138,"id":7,"shortTitle":"enterprise-integration-training-tools-news","color":"green","name":"Integration","code":"integration","url":"/enterprise-integration-training-tools-news"},{"topic":48,"id":8,"shortTitle":"iot-developer-tutorials-tools-news-reviews","color":"orange","name":"IoT","code":"iot","url":"/iot-developer-tutorials-tools-news-reviews"},{"topic":1,"id":1,"shortTitle":"java-jdk-development-tutorials-tools-news","color":"purple","name":"Java","code":"java","url":"/java-jdk-development-tutorials-tools-news"},{"topic":29,"id":9,"shortTitle":"mobile-app-developer-tutorials-tools-news","color":"yellow","name":"Mobile","code":"mobile","url":"/mobile-app-developer-tutorials-tools-news"},{"topic":653,"id":10,"shortTitle":"apm-tools-performance-monitoring-optimization","color":"red","name":"Performance","code":"performance","url":"/apm-tools-performance-monitoring-optimization"},{"topic":35,"id":11,"shortTitle":"web-development-programming-tutorials-tools-news","color":"orange","name":"Web Dev","code":"webdev","url":"/web-development-programming-tutorials-tools-news"}]],"matchedUrl":{"name":"dzone:articles:view","mapping":"/articles/**","mappingPatterns":{}},"requiresModule":["angulartics","angulartics.google.analytics","dndLists","generalDirectives","monospaced.elastic","angularFileUpload","akoenig.deckgrid","ui.bootstrap-slider","ngSanitize","ui.select","ui.bootstrap","angularMoment","ngTouch","ngDialog","LocalStorageModule"]}; } catch(e) { console.error(e); }
4
Notification
  • Adam Van Grack started following you

  • Jessica Conaghan, Gumption Scott and 6 commented on a link you posted

    T-Mobile Unvells Cheaper, More Basic 'Simple Prepaid' Phone Plans

  • Jessica Conaghan replied on a comment you posted

    CSS counters are one of those "oh neat, didn't know CSS could do that" features with a lot of Xubuntu 14.10 Utopic Unicorn is the latest release of xubuntu based on Ubuntu 14.10

  • Jessica Conaghan started following you

See All
POWERED BY DZone TeamHub
\r\nI use the DOMReady extension for Prototype's Event object, but you can use any loader you want. The Ajax.Responders.register part reruns the script after a drag-and-drop operation (or any Ajax operation really).\r\n\r\nDownload Scriptaculous and Prototype.\r\n\r\nvar FirstLast = {\r\n go: function(el) {\r\n el = $(el);\r\n\r\n // Whitespace nodes need to be cleaned to get the intended effect\r\n var children = Element.cleanWhitespace(el).childNodes;\r\n\r\n // Return if there are not any children\r\n if (0 == children.length) return\r\n \r\n if (1 == children.length) {\r\n // Cheap shortcut if there is only 1 child node\r\n children[0].addClassName(this._firstChildClassName);\r\n children[0].addClassName(this._lastChildClassName);\r\n } else {\r\n for (var i = 0; i < children.length; i++) {\r\n switch (i) {\r\n // First child\r\n case 0:\r\n children[i].addClassName(this._firstChildClassName);\r\n children[i].removeClassName(this._lastChildClassName);\r\n break;\r\n // Last child\r\n case children.length - 1:\r\n children[i].removeClassName(this._firstChildClassName);\r\n children[i].addClassName(this._lastChildClassName);\r\n break;\r\n // Every child other than the first or last\r\n default:\r\n children[i].removeClassName(this._firstChildClassName);\r\n children[i].removeClassName(this._lastChildClassName);\r\n break; // I know it is unnecessary\r\n }\r\n }\r\n }\r\n },\r\n // Pseudo Private methods and attributes\r\n _firstChildClassName: \"first\",\r\n _lastChildClassName: \"last\"\r\n};","source":null,"views":1,"articleDate":1159125392000,"tldr":null,"originalSource":"","published":true,"nComments":0,"articleType":"snippet"}]; WMODEL_DATA.perms = {"canDecidePick":false,"canPublish":false}; WMODEL_DATA.isPreview = false; WMODEL_DATA.OPTIONS = {}; TH.installWidgetController('article.content', 'articleContent7', WMODEL_DATA, typeof controller == 'function' ? controller : null, [{name: 'partners', data: true},{name: 'DEFAULT', data: true}], ' oUhbblYOaqbcblYOaqbcC', null); })(); (function() { function controller($scope, $service, $location, SideBarService, TH$Request) { SideBarService.ctx.pageSize = $scope.pageSize; SideBarService.ctx.isPreview = $scope.isPreview; SideBarService.ctx.mode = $scope.mode; SideBarService.fn.loader = $service; SideBarService.fn.scrollCheck = function() { $scope.$emit('thIfScrollCheck'); }; var currentFilter; $scope.$on('$locationChangeSuccess', function() { if (!$location.search().filter) { $scope.filter = 'latest'; } else { $scope.filter = $location.search().filter; if ($scope.filter == 'latest') { $location.search('filter', null); } } if (currentFilter == $scope.filter) { return; } currentFilter = $scope.filter; SideBarService.ctx.filter = $scope.filter; }); $scope.display = SideBarService.getList(); $scope.$watchCollection(function() { return SideBarService.getList(); }, function (n) { $scope.display = n; }); $scope.isActive = SideBarService.isActive; $scope.isExcluded = SideBarService.isExcluded; $scope.loadMore = SideBarService.load; $scope.loading = function() { return SideBarService.ctx.loading; } } var WMODEL_DATA = {}; WMODEL_DATA.pageSize = 20; WMODEL_DATA.isPreview = false; WMODEL_DATA.OPTIONS = {}; WMODEL_DATA.mode = null; TH.installWidgetController('sidebar.content.list', 'sidebarContentList10', WMODEL_DATA, typeof controller == 'function' ? controller : null, [{name: 'DEFAULT', data: true}], ' oUhbkSMaaqbcdvVkcC', null); })(); (function() { var WMODEL_DATA = {}; WMODEL_DATA.OPTIONS = {}; TH.installWidgetController('sidebar.tapBar', 'sidebar', WMODEL_DATA, typeof controller == 'function' ? controller : null, null, ' oUhbkSMadabfWVcC oUhbkSMadabbWQbVkcC', null); })(); (function() { function controller($scope, shareThis, TH$Dialog, TH$Service) { $scope.getEditUrl = function(id, type) { if (!type || type == 'article') { return '/content/' + id + '/edit.html'; } else { return '/dzone/staff/' + type + (type == 'refcard' ? 'z' : 's') + '/' + id + '/edit.html'; } } $scope.share = function(socialNet, url, title){ shareThis.shareThis(socialNet, url, title); }; $scope.canDelete = function(article) { return article.canDelete; } $scope.edit = function(link) { TH$Dialog.open({ loadWidget: 'links.postPreview', widgetArgs: { edit: link.id }, size: 'xbig' }).then(function (result) { $scope.link.title = result.title; $scope.link.linkDescription = result.content; $scope.link.thumb = result.thumb; $scope.link.tags = result.topics; }); }; $scope.deleteLink = function(article) { var title = article.title; var type = 'link'; if(article.header){ title = (article.header.type == 'article') ? article.header.title : article.title; type = (article.header.type == 'article') ? 'article' : 'link'; } TH$Dialog.confirm('Do you want to delete "' + title + '"?').then(function() { return TH$Service.action('delete', {type: type, id: article.id}); }).then(function() { article.deleted = true; }); }; } var WMODEL_DATA = {}; WMODEL_DATA.OPTIONS = {}; TH.installWidgetController('content.commentsSlider', 'contentCommentsSlider9', WMODEL_DATA, typeof controller == 'function' ? controller : null, null, ' oUhbaqbcaibvnWffWVcC', null); })(); (function() { var WMODEL_DATA = {}; WMODEL_DATA.name = "commentsSlider"; WMODEL_DATA.slot = null; WMODEL_DATA.OPTIONS = {"name":"commentsSlider"}; TH.installWidgetController('components.slider', 'componentsSlider8', WMODEL_DATA, typeof controller == 'function' ? controller : null, null, ' oUhballbvbdSaoUhM', null); })();