Skip to content

Instantly share code, notes, and snippets.

@krisbulman
Created March 10, 2015 18:46
Show Gist options
  • Save krisbulman/1cb34c1c0b9f280a0478 to your computer and use it in GitHub Desktop.
Save krisbulman/1cb34c1c0b9f280a0478 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
<div class="centre">
<h1>Understanding JavaScript Behaviors in Drupal</h1>
<p class="text--hecto">I can barely remember the first time I added JavaScript to a Drupal page using a custom module. I'm sure looked at the documentation, took the example snippet, tweaked it, tested it, and moved on to something else. It was only later, using a debugger, that I saw how Drupal's "behavior" system worked and realized that my code was not being executed as I expected.</p>
<p class="text--base">In this article we' cover the key facts about Drupal behaviours, then look at a real Drupal project to inspect it's behaviours and optimize them.</p>
<h2>Unraveling Drupal behaviors</h2>
<p>Drupal’s official JavaScript documentation suggests that modules should implement JavaScript by attaching logic to Drupal.behaviors. Here is an example taken from that page:</p>
<p class="text--centi">heading default metadata</p>
<p class="text--kilo">in-content quote/highlight</p>
<p>Some regular text</p></div>
</div>
// ----
// libsass (v3.1.0)
// ----
@import 'susy';
$base-font-size: 16px;
@function strip-unit($num) {
@return $num / ($num * 0 + 1);
}
@function rem($values, $base-font-size: $base-font-size) {
// Create an empty list to append to.
$rem: ();
@each $value in $values {
@if unit($value) == 'px' {
// Retain 0 or auto
@if $value == 0 or $value == auto {
$rem: append($rem, $value);
} @else {
// Convert the units and append them to the list
$val: $value / $base-font-size;
// scss-lint:disable ZeroUnit
$rem-val: strip-unit($val) + 0rem;
// scss-lint:enable ZeroUnit
$rem: append($rem, $rem-val);
}
} @else {
@warn '#{$value} is not a supported unit (px)';
@return null
}
}
@return $rem;
}
@mixin respond-to($name, $layout: false, $no-query: $susy-media-fallback) {
// If the key exists in the map
@if map-has-key($breakpoints, $name) {
// Prints a media query based on the value
@include susy-breakpoint(inspect(map-get($breakpoints, $name)), $layout, $no-query) {
@content;
}
} @else {
// If the key doesn't exist in the map
@warn 'Unfortunately, no value could be retrieved from `#{$breakpoints}`. '
+ 'Please make sure it is defined in `$breakpoints` map.';
}
}
// config/_breakpoints.scss
$breakpoints: (
washer: 20em,
bolt: 48em,
head: 80em
);
// config/_typography.scss
$text-sizing: (
centi: ( // heading default meta data
washer: (
font-size: rem(12px),
line-height: 1.5
),
bolt: (
font-size: rem(16px),
line-height: 1.5
)
),
base: ( // base article body text
washer: (
font-size: rem(16px),
line-height: 1.75,
margin-bottom: rem(30px)
),
bolt: (
font-size: rem(18px),
line-height: 1.75
),
head: (
font-size: rem(20px),
line-height: 1.75
)
),
deca: ( // h3
washer: (
font-size: rem(18px),
line-height: 1.25,
margin-bottom: rem(12px)
),
bolt: (
font-size: rem(20px),
line-height: 1.25
)
),
hecto: ( // article intro
washer: (
font-size: rem(20px),
line-height: 1.5,
margin-bottom: rem(32px)
),
bolt: (
font-size: rem(24px),
line-height: 1.5
),
head: (
font-size: rem(26px),
line-height: 1.5
)
),
kilo: ( // in content quote/highlight
washer: (
font-size: rem(20px),
line-height: 1.5,
margin-bottom: rem(32px)
),
bolt: (
font-size: rem(24px),
line-height: 1.5
),
head: (
font-size: rem(28px),
line-height: 1.5
)
),
mega: ( // h2
washer: (
font-size: rem(28px),
line-height: 1.25,
margin-bottom: rem(8px)
)
),
giga: ( // h1
washer: (
font-size: rem(28px),
line-height: 1.125,
margin-bottom: rem(24px)
),
bolt: (
font-size: rem(54px),
line-height: 1.125,
margin-bottom: rem(32px)
),
head: (
font-size: rem(64px),
line-height: 1.125
)
)
);
// lib/functions/_responsive.scss
@function breakpoint($breakpoint-name) {
@return map-get($breakpoints, $breakpoint-name);
}
// lib/functions/_typography.scss
@function text-breakpoints-for($text-size) {
@return map-get($text-sizing, $text-size);
}
@function text-properties-for($text-size, $breakpoint-name) {
$text-breakpoints-map: text-breakpoints-for($text-size);
@return map-get($text-breakpoints-map, $breakpoint-name);
}
// lib/mixins/_typography.scss
@mixin text-size($text-size, $breakpoint-name: "washer") {
$text-size-properties: text-properties-for($text-size, $breakpoint-name);
@if $text-size-properties != null {
font-size: map-get($text-size-properties, "font-size");
line-height: map-get($text-size-properties, "line-height");
margin-top: map-get($text-size-properties, "margin-top");
margin-bottom: map-get($text-size-properties, "margin-bottom");
} @else {
@warn "Breakpoint '#{$breakpoint-name}' for text size '#{$text-size}' is not defined";
}
}
@mixin responsive-text-size($text-size, $default-breakpoint: "washer") {
@include text-size($text-size, $default-breakpoint);
$text-breakpoints-map: text-breakpoints-for($text-size);
$text-breakpoints-keys: map-keys($text-breakpoints-map);
@each $breakpoint-name in $text-breakpoints-keys {
@if $breakpoint-name != $default-breakpoint and map-get($breakpoints, $breakpoint-name) != null {
@include respond-to($breakpoint-name) {
@include text-size($text-size, $breakpoint-name);
}
}
}
}
html {
font-size: 100%;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.centre {
width: 800px;
margin: 0 auto;
}
// _typography.scss
// Article and Page Titles h1
h1,
.text--mega {
@include responsive-text-size("giga");
}
// Long form content h2 or in-content sub-heading
h2,
.text--kilo {
@include responsive-text-size("mega");
}
// Long form content h3 or in-content sub sub-heading
h3,h4,h5,h6
.text--deca {
@include responsive-text-size("deca");
}
// Long-form body copy paragraph text
.text--base, body {
@include responsive-text-size("base");
}
// heading default metadata
.text--centi {
@include responsive-text-size("centi");
}
// article intro paragraph
.text--hecto {
@include responsive-text-size("hecto");
}
// in-content quote/highlight
.text--kilo {
@include responsive-text-size("kilo");
}
html {
font-size: 100%;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
.centre {
width: 800px;
margin: 0 auto; }
h1, .text--mega {
font-size: 1.75rem;
line-height: 1.125;
margin-bottom: 1.5rem; }
@media (min-width: 48em) {
h1, .text--mega {
font-size: 3.375rem;
line-height: 1.125;
margin-bottom: 2rem; } }
@media (min-width: 80em) {
h1, .text--mega {
font-size: 4rem;
line-height: 1.125; } }
h2, .text--kilo {
font-size: 1.75rem;
line-height: 1.25;
margin-bottom: 0.5rem; }
h3, h4, h5, h6 .text--deca {
font-size: 1.125rem;
line-height: 1.25;
margin-bottom: 0.75rem; }
@media (min-width: 48em) {
h3, h4, h5, h6 .text--deca {
font-size: 1.25rem;
line-height: 1.25; } }
.text--base, body {
font-size: 1rem;
line-height: 1.75;
margin-bottom: 1.875rem; }
@media (min-width: 48em) {
.text--base, body {
font-size: 1.125rem;
line-height: 1.75; } }
@media (min-width: 80em) {
.text--base, body {
font-size: 1.25rem;
line-height: 1.75; } }
.text--centi {
font-size: 0.75rem;
line-height: 1.5; }
@media (min-width: 48em) {
.text--centi {
font-size: 1rem;
line-height: 1.5; } }
.text--hecto {
font-size: 1.25rem;
line-height: 1.5;
margin-bottom: 2rem; }
@media (min-width: 48em) {
.text--hecto {
font-size: 1.5rem;
line-height: 1.5; } }
@media (min-width: 80em) {
.text--hecto {
font-size: 1.625rem;
line-height: 1.5; } }
.text--kilo {
font-size: 1.25rem;
line-height: 1.5;
margin-bottom: 2rem; }
@media (min-width: 48em) {
.text--kilo {
font-size: 1.5rem;
line-height: 1.5; } }
@media (min-width: 80em) {
.text--kilo {
font-size: 1.75rem;
line-height: 1.5; } }
<div class="centre">
<h1>Understanding JavaScript Behaviors in Drupal</h1>
<p class="text--hecto">I can barely remember the first time I added JavaScript to a Drupal page using a custom module. I'm sure looked at the documentation, took the example snippet, tweaked it, tested it, and moved on to something else. It was only later, using a debugger, that I saw how Drupal's "behavior" system worked and realized that my code was not being executed as I expected.</p>
<p class="text--base">In this article we' cover the key facts about Drupal behaviours, then look at a real Drupal project to inspect it's behaviours and optimize them.</p>
<h2>Unraveling Drupal behaviors</h2>
<p>Drupal’s official JavaScript documentation suggests that modules should implement JavaScript by attaching logic to Drupal.behaviors. Here is an example taken from that page:</p>
<p class="text--centi">heading default metadata</p>
<p class="text--kilo">in-content quote/highlight</p>
<p>Some regular text</p></div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment