enmi12/glossaire/_posts/docs/2011-05-25-extending-isotope.mdown
author ymh <ymh.work@gmail.com>
Mon, 08 Sep 2025 19:44:41 +0200
changeset 23 417f20492bf7
parent 0 d970ebf37754
permissions -rwxr-xr-x
Update Docker configuration and plugin versions - Upgrade MariaDB from 10.6 to 11 with auto-upgrade support - Add WordPress debug environment variable to FPM container - Update PHP-FPM Dockerfile base image - Update Include Mastodon Feed plugin with bug fixes and improvements - Update Portfolio plugin (v2.58) with latest translations and demo data enhancements - Remove old README.md from Mastodon Feed plugin 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
---
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
title: Extending Isotope
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
category: docs
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
layout: default
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
toc:
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
  - { title: Custom layout modes, anchor: custom_layout_modes }
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
---
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
Isotope uses a constructor pattern, `$.Isotope`. To extend Isotope, you need only to add a method to `$.Isotope.prototype`.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
$.Isotope.prototype.myMethod = function() { ... };
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
// or, using jQuery extend utility
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
$.extend( $.Isotope.prototype, {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
  myMethod : function() { ... }
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
});
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
Before diving in, try [looking over the source](../jquery.isotope.js) to get a better understand of the internal logic behind Isotope.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
## Custom layout modes
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
Isotope's layout modes are built around four methods: `Reset`, `Layout`, `GetContainerSize`, and `ResizeChanged`. These methods are the hooks that allow you to develop your own custom layout mode, without getting your hands dirty dealing with sorting, filtering, or other functionality. These layout mode methods need to be prefixed with an underscore and the name of the layout mode.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
// adding layout mode methods for 'customMode'
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
$.extend( $.Isotope.prototype, {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
  _customModeReset : function() { ... },
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
  _customModeLayout : function( $elems ) { ... },
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
  _customModeGetContainerSize : function() { ... },
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
  _customModeResizeChanged : function() { ... }
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
});
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
[**See Custom layout mode: Category Rows**](../custom-layout-modes/category-rows.html)
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
[**See Custom layout mode: Spine align**](../custom-layout-modes/spine-align.html)
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
All of the [default layout modes](../docs/layout-modes.html) follow this pattern. We'll look at the code behind the _fitRows_ layout mode.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
### Reset
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
Each layout mode should have its own set of properties that only it can use and not be affected by other layout modes. These properties can be accessed in the instance as an object whose value matches the layout mode name (i.e. `this.fitRows` for _fitRows_).
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
The `Reset` layout mode method is called with every `reLayout`, where Isotope will go through each item element and position it. This method resets layout mode properties.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
The _fitRows_ layout mode keeps track of x and y position, as well as the height of the container. These properties are set back to zero in `Reset`.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
_fitRowsReset : function() {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
  this.fitRows = {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
    x : 0,
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
    y : 0,
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
    height : 0
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
  };
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
},
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
### Layout
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
The `Layout` layout mode method is where items are positioned. Most of your layout logic happens here. This method provides one argument `$elems` -- a jQuery object with the item elements that need to be positioned.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
`$elems.each` is the principle loop, iterating over each item element and positioning it. Items are positioned with the `_pushPosition` method (see below). The layout modes properties are 
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
For _fitRows_, items are placed with the `this.fitRows.x` and `this.fitRows.y` values. This position is determined by if the item can fit in the current row, or if a new row needs to be started.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
_fitRowsLayout : function( $elems ) {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
  var instance = this,
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
      containerWidth = this.element.width(),
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
      props = this.fitRows;
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
  
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
  $elems.each( function() {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
    var $this = $(this),
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
        atomW = $this.outerWidth(true),
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
        atomH = $this.outerHeight(true);
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
  
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
    if ( props.x !== 0 && atomW + props.x > containerWidth ) {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
      // if this element cannot fit in the current row
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
      props.x = 0;
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
      props.y = props.height;
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
    } 
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
  
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
    // position the atom
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
    instance._pushPosition( $this, props.x, props.y );
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
    props.height = Math.max( props.y + atomH, props.height );
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
    props.x += atomW;
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
  });
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
},
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
### GetContainerSize
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
After the script goes through positioning each item, it needs to resize the container. `GetContainerSize` returns the style for the size of the container.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
In _fitRows_, the height property is returned as the value for height.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
_fitRowsGetContainerSize : function () {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
  return { height : this.fitRows.height };
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
},
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
### ResizeChanged
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
`ResizeChanged` is triggered whenever the browser window is resized. Before Isotope adjusts the layout, this method is triggered to determine if the layout has actually changed. The methods return a boolean.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
_fitRowsResizeChanged : function() {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
  return true;
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
},
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
### Helper methods
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
The `_pushPosition` method is used within a layout mode's `Layout` method. It takes 3 arguments: the item element currently being positioned, the x position, and the y position.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
_pushPosition( $item, x, y )
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
`_getSegments` is used within the layout mode's `Reset` method. It performs several utilities:
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
+ Determines the `columnWidth` for the layout mode (`rowHeight` for horizontal layout modes). This is either passed in as an option (i.e. `masonry { columnWidth: 90 }`), or the width of the first item element. This property is then set for the layout mode, i.e. `this.masonry.columnWidth`.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
+ Calculates the number of number of columns (or rows, if horizontal) given the size of the container. This property is then set for the layout mode, i.e. `this.masonry.cols`.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
_getSegments( isHorizontal )
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
// for example
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
_cellsByRowReset : function() {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
  this.cellsByRow = {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
    index : 0
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
  };
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
  // get this.cellsByRow.columnWidth
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
  this._getSegments();
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
  // get this.cellsByRow.rowHeight
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
  this._getSegments(true);
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
},
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
Similarly, `_checkIfSegmentsChanged` is used within `ResizeChanged`. It returns a boolean indicating whether or not the number of columns or rows has changed since the window has been resized.
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
{% highlight javascript %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
_checkIfSegmentsChanged( isHorizontal )
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
// for example
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
_masonryResizeChanged : function() {
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
  return this._checkIfSegmentsChanged();
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
},
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
{% endhighlight %}
d970ebf37754 first import
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174