├── .editorconfig
├── .gitattributes
├── .gitignore
├── .jshintrc
├── .npmignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── dist
├── owl.carousel2.thumbs.js
└── owl.carousel2.thumbs.min.js
├── package.json
└── src
└── owl.carousel2.thumbs.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | indent_style = space
11 | indent_size = 4
12 |
13 | end_of_line = lf
14 | charset = utf-8
15 | trim_trailing_whitespace = true
16 | insert_final_newline = true
17 |
18 | [*.md]
19 | trim_trailing_whitespace = false
20 |
21 | [{*.json,*.yml}]
22 | indent_size = 2
23 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | _site
4 | *.zip
5 | *.rar
6 | /.idea
7 | /demo
8 |
9 | # Ignore files beginning with a #
10 | \#*
11 |
12 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": true,
4 | "esnext": true,
5 | "bitwise": true,
6 | "camelcase": false,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "immed": true,
10 | "indent": 4,
11 | "latedef": true,
12 | "newcap": true,
13 | "noarg": true,
14 | "quotmark": "single",
15 | "regexp": true,
16 | "undef": true,
17 | "unused": true,
18 | "strict": true,
19 | "trailing": true,
20 | "smarttabs": true,
21 | "asi" : true,
22 | "boss" : true,
23 | "browser" : true,
24 | "debug" : true,
25 | "devel" : true,
26 | "eqeqeq" : false,
27 | "eqnull" : true,
28 | "expr" : true,
29 | "laxbreak" : true,
30 | "unused" : false,
31 | "validthis": true,
32 | "globals": {
33 | "jQuery": true,
34 | "define": true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .editorconfig
2 | .gitattributes
3 | .gitignore
4 | .jshintrc
5 | .travis.yml
6 | *.zip
7 | *.rar
8 |
9 | bower.json
10 | /example
11 | /.idea
12 | /demo
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | 'use strict';
4 |
5 | // Load grunt tasks automatically
6 | require('load-grunt-tasks')(grunt);
7 |
8 | // Time how long tasks take. Can help when optimizing build times
9 | require('time-grunt')(grunt);
10 |
11 | // Project configuration.
12 | grunt.initConfig({
13 |
14 | config: {
15 | src: 'src',
16 | dist: 'dist'
17 | },
18 |
19 | pkg: require('./package'),
20 |
21 | meta: {
22 | banner: '/*! <%= pkg.name %> - v<%= pkg.version %> | ' +
23 | '(c) <%= grunt.template.today("yyyy") %> @gijsroge | ' +
24 | '<%= pkg.license.type %> license | <%= pkg.homepage %> */\n'
25 | },
26 |
27 | // Watches files for changes and runs tasks based on the changed files
28 | watch: {
29 | jshint: {
30 | files: '<%= config.src %>/{,*/}*.js',
31 | tasks: ['jshint']
32 | },
33 |
34 | concat: {
35 | files: '<%= config.src %>/{,*/}*.js',
36 | tasks: ['concat:dist', 'uglify:dist']
37 | }
38 | },
39 |
40 | // Make sure code styles are up to par and there are no obvious mistakes
41 | jshint: {
42 | options: {
43 | jshintrc: '.jshintrc',
44 | reporter: require('jshint-stylish')
45 | },
46 | all: [
47 | 'Gruntfile.js',
48 | '<%= config.src %>/{,*/}*.js'
49 | ],
50 | },
51 |
52 | // Prepend a banner to the files
53 | concat: {
54 | options: {
55 | banner: '<%= meta.banner %>'
56 | },
57 | dist: {
58 | src: ['<%= config.src %>/<%= pkg.name %>.js'],
59 | dest: '<%= config.dist %>/<%= pkg.name %>.js'
60 | }
61 | },
62 |
63 | // Generate a minified version
64 | uglify: {
65 | options: {
66 | banner: '<%= meta.banner %>'
67 | },
68 | dist: {
69 | src: ['<%= config.dist %>/<%= pkg.name %>.js'],
70 | dest: '<%= config.dist %>/<%= pkg.name %>.min.js'
71 | }
72 | },
73 |
74 | // Increment version
75 | bump: {
76 | options: {
77 | files: [
78 | 'bower.json',
79 | 'package.json',
80 | '<%= pkg.name %>.jquery.json'
81 | ],
82 | updateConfigs: ['pkg'],
83 | commitMessage: 'v%VERSION%',
84 | commitFiles: [
85 | 'bower.json',
86 | 'package.json',
87 | 'dist'
88 | ],
89 | createTag: false,
90 | push: true,
91 | pushTo: 'origin master'
92 | }
93 | },
94 |
95 | //create package
96 | compress: {
97 | main: {
98 | options: {
99 | archive: '<%= pkg.name %>-v<%= pkg.version %>.zip'
100 | },
101 | expand: true,
102 | cwd: '<%= config.dist %>/',
103 | src: ['**/*'],
104 | dest: '/'
105 | }
106 | }
107 | });
108 |
109 | // Build task
110 | grunt.registerTask('build', ['jshint', 'concat:dist', 'uglify:dist']);
111 |
112 | // Release task
113 | grunt.registerTask('release', [
114 | 'bump-only',
115 | 'build',
116 | 'compress:main',
117 | 'bump-commit'
118 | ]);
119 | };
120 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 gijsroge
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Owl Carousel 2 Thumbnails plugin
2 | Enables thumbnail support for Owl Carousel 2.0
3 |
4 | ## Quick start
5 | grab the [latest release](https://github.com/gijsroge/OwlCarousel2-Thumbs/archive/0.1.7.tar.gz) and slam it behind the default owl carousel plugin.
6 |
7 | ##### Enable thumbs
8 | ```javascript
9 | $(document).ready(function(){
10 | $('.owl-carousel').owlCarousel({
11 | thumbs: true
12 | });
13 | });
14 | ```
15 |
16 | ## Use pre-rendered html as thumbnails. **_recommended_**
17 | ```javascript
18 | $(document).ready(function(){
19 | $('.owl-carousel').owlCarousel({
20 | thumbs: true,
21 | thumbsPrerendered: true
22 | });
23 | });
24 | ```
25 |
26 | ##### Add thumbnails (link slider and thumbnails with data-slider-id attribute)
27 | ```html
28 |
29 |
Your Content
30 |
Your Content
31 |
Your Content
32 |
Your Content
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | ```
41 |
42 | ## Or add data-thumb attribute to your slides
43 | ```html
44 |
45 |
Your Content
46 |
Your Content
47 |
Your Content
48 |
Your Content
49 |
50 | ```
51 |
52 | #### [demo](http://gijsroge.github.io/owl-carousel2-thumbs)
53 |
54 | ## Available options
55 | ```javascript
56 | $(document).ready(function(){
57 | $('.owl-carousel').owlCarousel({
58 | // Enable thumbnails
59 | thumbs: true,
60 |
61 | // When only using images in your slide (like the demo) use this option to dynamicly create thumbnails without using the attribute data-thumb.
62 | thumbImage: false,
63 |
64 | // Enable this if you have pre-rendered thumbnails in your html instead of letting this plugin generate them. This is recommended as it will prevent FOUC
65 | thumbsPrerendered: true,
66 |
67 | // Class that will be used on the thumbnail container
68 | thumbContainerClass: 'owl-thumbs',
69 |
70 | // Class that will be used on the thumbnail item's
71 | thumbItemClass: 'owl-thumb-item'
72 | });
73 | });
74 | ```
75 |
76 | ## npm
77 | ```
78 | npm install owl.carousel2.thumbs
79 | ```
80 |
81 | ## bower
82 | ```
83 | bower install owl.carousel2.thumbs
84 | ```
85 |
86 | > with <3 in Belgium by [@GijsRoge](https://twitter.com/GijsRoge)
87 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "owl.carousel2.thumbs",
3 | "version": "0.1.8",
4 | "homepage": "https://github.com/gijsroge/OwlCarousel2-Thumbs",
5 | "authors": [
6 | { "name" : "Gijs Rogé",
7 | "homepage" : "http://twitter.com/gijsroge"
8 | }
9 | ],
10 | "description": "Enables thumbnail support for Owl Carousel 2.0",
11 | "main": "dist/owl.carousel2.thumbs.min.js",
12 | "license": "MIT",
13 | "keywords": [
14 | "Owl",
15 | "Carousel",
16 | "Thumbs",
17 | "Thumbnails",
18 | "jQuery"
19 | ],
20 | "ignore": [
21 | "**/.*",
22 | "*.json",
23 | "src",
24 | "example",
25 | "node_modules",
26 | "bower_components",
27 | "Gruntfile.js"
28 | ],
29 | "repository" :
30 | {
31 | "type" : "git",
32 | "url" : "https://github.com/gijsroge/OwlCarousel2-Thumbs"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/dist/owl.carousel2.thumbs.js:
--------------------------------------------------------------------------------
1 | /*! owl.carousel2.thumbs - v0.1.8 | (c) 2016 @gijsroge | MIT license | https://github.com/gijsroge/OwlCarousel2-Thumbs */
2 | /**
3 | * Thumbs Plugin
4 | * @version 2.0.0
5 | * @author Gijs Rogé
6 | * @license The MIT License (MIT)
7 | */
8 | (function ($, window, document, undefined) {
9 | 'use strict';
10 |
11 | /**
12 | * Creates the thumbs plugin.
13 | * @class The thumbs Plugin
14 | * @param {Owl} carousel - The Owl Carousel
15 | */
16 | var Thumbs = function (carousel) {
17 |
18 |
19 | /**
20 | * Reference to the core.
21 | * @protected
22 | * @type {Owl}
23 | */
24 | this.owl = carousel;
25 |
26 |
27 | /**
28 | * All DOM elements for thumbnails
29 | * @protected
30 | * @type {Object}
31 | */
32 | this._thumbcontent = [];
33 |
34 |
35 | /**
36 | * Instance identiefier
37 | * @type {number}
38 | * @private
39 | */
40 | this._identifier = 0;
41 |
42 |
43 | /**
44 | * Return current item regardless of clones
45 | * @protected
46 | * @type {Object}
47 | */
48 | this.owl_currentitem = this.owl.options.startPosition;
49 |
50 |
51 | /**
52 | * The carousel element.
53 | * @type {jQuery}
54 | */
55 | this.$element = this.owl.$element;
56 |
57 |
58 | /**
59 | * All event handlers.
60 | * @protected
61 | * @type {Object}
62 | */
63 | this._handlers = {
64 | 'prepared.owl.carousel': $.proxy(function (e) {
65 | if (e.namespace && this.owl.options.thumbs && !this.owl.options.thumbImage && !this.owl.options.thumbsPrerendered && !this.owl.options.thumbImage) {
66 | if ($(e.content).find('[data-thumb]').attr('data-thumb') !== undefined) {
67 | this._thumbcontent.push($(e.content).find('[data-thumb]').attr('data-thumb'));
68 | }
69 | } else if (e.namespace && this.owl.options.thumbs && this.owl.options.thumbImage) {
70 | var innerImage = $(e.content).find('img');
71 | this._thumbcontent.push(innerImage);
72 | }
73 | }, this),
74 |
75 | 'initialized.owl.carousel': $.proxy(function (e) {
76 | if (e.namespace && this.owl.options.thumbs) {
77 | this.render();
78 | this.listen();
79 | this._identifier = this.owl.$element.data('slider-id');
80 | this.setActive();
81 | }
82 | }, this),
83 |
84 | 'changed.owl.carousel': $.proxy(function (e) {
85 | if (e.namespace && e.property.name === 'position' && this.owl.options.thumbs) {
86 | this._identifier = this.owl.$element.data('slider-id');
87 | this.setActive();
88 | }
89 | }, this)
90 | };
91 |
92 | // set default options
93 | this.owl.options = $.extend({}, Thumbs.Defaults, this.owl.options);
94 |
95 | // register the event handlers
96 | this.owl.$element.on(this._handlers);
97 | };
98 |
99 |
100 | /**
101 | * Default options.
102 | * @public
103 | */
104 | Thumbs.Defaults = {
105 | thumbs: true,
106 | thumbImage: false,
107 | thumbContainerClass: 'owl-thumbs',
108 | thumbItemClass: 'owl-thumb-item',
109 | moveThumbsInside: false
110 | };
111 |
112 |
113 | /**
114 | * Listen for thumbnail click
115 | * @protected
116 | */
117 | Thumbs.prototype.listen = function () {
118 |
119 | //set default options
120 | var options = this.owl.options;
121 |
122 | if (options.thumbsPrerendered) {
123 | this._thumbcontent._thumbcontainer = $('.' + options.thumbContainerClass);
124 | }
125 |
126 | //check what thumbitem has been clicked and move slider to that item
127 | $(this._thumbcontent._thumbcontainer).on('click', this._thumbcontent._thumbcontainer.children(), $.proxy(function (e) {
128 |
129 | // find relative slider
130 | this._identifier = $(e.target).closest('.' + options.thumbContainerClass).data('slider-id');
131 |
132 | // get index of clicked thumbnail
133 | var index = $(e.target).parent().is(this._thumbcontent._thumbcontainer) ? $(e.target).index() : $(e.target).closest('.'+options.thumbItemClass).index();
134 |
135 | if (options.thumbsPrerendered) {
136 | // slide to slide :)
137 | $('[data-slider-id=' + this._identifier + ']').trigger('to.owl.carousel', [index, options.dotsSpeed, true]);
138 | } else {
139 | this.owl.to(index, options.dotsSpeed);
140 | }
141 |
142 | e.preventDefault();
143 | }, this));
144 | };
145 |
146 |
147 | /**
148 | * Builds thumbnails
149 | * @protected
150 | */
151 | Thumbs.prototype.render = function () {
152 |
153 | //set default options
154 | var options = this.owl.options;
155 |
156 | //create thumbcontainer
157 | if (!options.thumbsPrerendered) {
158 | this._thumbcontent._thumbcontainer = $('').addClass(options.thumbContainerClass).appendTo(this.$element);
159 | } else {
160 | this._thumbcontent._thumbcontainer = $('.' + options.thumbContainerClass + '');
161 | if(options.moveThumbsInside){
162 | this._thumbcontent._thumbcontainer.appendTo(this.$element);
163 | }
164 | }
165 |
166 | //create thumb items
167 | var i;
168 | if (!options.thumbImage) {
169 | for (i = 0; i < this._thumbcontent.length; ++i) {
170 | this._thumbcontent._thumbcontainer.append('
');
171 | }
172 | } else {
173 | for (i = 0; i < this._thumbcontent.length; ++i) {
174 | this._thumbcontent._thumbcontainer.append('
');
175 | }
176 | }
177 | };
178 |
179 |
180 | /**
181 | * Updates active class on thumbnails
182 | * @protected
183 | */
184 | Thumbs.prototype.setActive = function () {
185 |
186 | // get startslide
187 | this.owl_currentitem = this.owl._current - (this.owl._clones.length / 2);
188 | if (this.owl_currentitem === this.owl._items.length) {
189 | this.owl_currentitem = 0;
190 | }
191 |
192 | //set default options
193 | var options = this.owl.options;
194 |
195 | // set relative thumbnail container
196 | var thumbContainer = options.thumbsPrerendered ? $('.' + options.thumbContainerClass + '[data-slider-id="' + this._identifier + '"]') : this._thumbcontent._thumbcontainer;
197 | thumbContainer.children().filter('.active').removeClass('active');
198 | thumbContainer.children().eq(this.owl_currentitem).addClass('active');
199 | };
200 |
201 |
202 | /**
203 | * Destroys the plugin.
204 | * @public
205 | */
206 | Thumbs.prototype.destroy = function () {
207 | var handler, property;
208 | for (handler in this._handlers) {
209 | this.owl.$element.off(handler, this._handlers[handler]);
210 | }
211 | for (property in Object.getOwnPropertyNames(this)) {
212 | typeof this[property] !== 'function' && (this[property] = null);
213 | }
214 | };
215 |
216 | $.fn.owlCarousel.Constructor.Plugins.Thumbs = Thumbs;
217 |
218 | })(window.Zepto || window.jQuery, window, document);
--------------------------------------------------------------------------------
/dist/owl.carousel2.thumbs.min.js:
--------------------------------------------------------------------------------
1 | /*! owl.carousel2.thumbs - v0.1.8 | (c) 2016 @gijsroge | MIT license | https://github.com/gijsroge/OwlCarousel2-Thumbs */
2 | !function(a,b,c,d){"use strict";var e=function(b){this.owl=b,this._thumbcontent=[],this._identifier=0,this.owl_currentitem=this.owl.options.startPosition,this.$element=this.owl.$element,this._handlers={"prepared.owl.carousel":a.proxy(function(b){if(!b.namespace||!this.owl.options.thumbs||this.owl.options.thumbImage||this.owl.options.thumbsPrerendered||this.owl.options.thumbImage){if(b.namespace&&this.owl.options.thumbs&&this.owl.options.thumbImage){var c=a(b.content).find("img");this._thumbcontent.push(c)}}else a(b.content).find("[data-thumb]").attr("data-thumb")!==d&&this._thumbcontent.push(a(b.content).find("[data-thumb]").attr("data-thumb"))},this),"initialized.owl.carousel":a.proxy(function(a){a.namespace&&this.owl.options.thumbs&&(this.render(),this.listen(),this._identifier=this.owl.$element.data("slider-id"),this.setActive())},this),"changed.owl.carousel":a.proxy(function(a){a.namespace&&"position"===a.property.name&&this.owl.options.thumbs&&(this._identifier=this.owl.$element.data("slider-id"),this.setActive())},this)},this.owl.options=a.extend({},e.Defaults,this.owl.options),this.owl.$element.on(this._handlers)};e.Defaults={thumbs:!0,thumbImage:!1,thumbContainerClass:"owl-thumbs",thumbItemClass:"owl-thumb-item",moveThumbsInside:!1},e.prototype.listen=function(){var b=this.owl.options;b.thumbsPrerendered&&(this._thumbcontent._thumbcontainer=a("."+b.thumbContainerClass)),a(this._thumbcontent._thumbcontainer).on("click",this._thumbcontent._thumbcontainer.children(),a.proxy(function(c){this._identifier=a(c.target).closest("."+b.thumbContainerClass).data("slider-id");var d=a(c.target).parent().is(this._thumbcontent._thumbcontainer)?a(c.target).index():a(c.target).closest("."+b.thumbItemClass).index();b.thumbsPrerendered?a("[data-slider-id="+this._identifier+"]").trigger("to.owl.carousel",[d,b.dotsSpeed,!0]):this.owl.to(d,b.dotsSpeed),c.preventDefault()},this))},e.prototype.render=function(){var b=this.owl.options;b.thumbsPrerendered?(this._thumbcontent._thumbcontainer=a("."+b.thumbContainerClass),b.moveThumbsInside&&this._thumbcontent._thumbcontainer.appendTo(this.$element)):this._thumbcontent._thumbcontainer=a("
").addClass(b.thumbContainerClass).appendTo(this.$element);var c;if(b.thumbImage)for(c=0;c
');else for(c=0;c
"+this._thumbcontent[c]+"")},e.prototype.setActive=function(){this.owl_currentitem=this.owl._current-this.owl._clones.length/2,this.owl_currentitem===this.owl._items.length&&(this.owl_currentitem=0);var b=this.owl.options,c=b.thumbsPrerendered?a("."+b.thumbContainerClass+'[data-slider-id="'+this._identifier+'"]'):this._thumbcontent._thumbcontainer;c.children().filter(".active").removeClass("active"),c.children().eq(this.owl_currentitem).addClass("active")},e.prototype.destroy=function(){var a,b;for(a in this._handlers)this.owl.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Thumbs=e}(window.Zepto||window.jQuery,window,document);
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "owl.carousel2.thumbs",
3 | "title": "Owl Carousel 2 Thumbnails",
4 | "description": "Enables thumbnail support for Owl Carousel 2.0",
5 | "version": "0.1.8",
6 | "main": "dist/owl.carousel2.thumbs.min.js",
7 | "homepage": "https://github.com/gijsroge/OwlCarousel2-Thumbs",
8 | "author": {
9 | "name": "Gijs Rogé",
10 | "url": "http://twitter.com/gijsroge"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/gijsroge/OwlCarousel2-Thumbs.git"
15 | },
16 | "keywords": [
17 | "Owl",
18 | "Carousel",
19 | "Thumbs",
20 | "Thumbnails",
21 | "jQuery"
22 | ],
23 | "license": {
24 | "type": "MIT",
25 | "url": "https://github.com/gijsroge/OwlCarousel2-Thumbs/blob/master/LICENSE"
26 | },
27 | "bugs": {
28 | "url": "https://github.com/gijsroge/OwlCarousel2-Thumbs/issues"
29 | },
30 | "engines": {
31 | "node": ">=0.8.0"
32 | },
33 | "dependencies": {},
34 | "devDependencies": {
35 | "crayola": "0.0.1",
36 | "grunt": "~0.4.2",
37 | "grunt-bump": "0.0.15",
38 | "grunt-contrib-compress": "^0.13.0",
39 | "grunt-contrib-concat": "~0.3.0",
40 | "grunt-contrib-jshint": "~0.8.0",
41 | "grunt-contrib-uglify": "~0.2.7",
42 | "grunt-contrib-watch": "~0.5.2",
43 | "jshint-stylish": "~0.1.5",
44 | "load-grunt-tasks": "~0.2.1",
45 | "time-grunt": "~0.2.7"
46 | },
47 | "scripts": {
48 | "test": "grunt jshint"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/owl.carousel2.thumbs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Thumbs Plugin
3 | * @version 2.0.0
4 | * @author Gijs Rogé
5 | * @license The MIT License (MIT)
6 | */
7 | (function ($, window, document, undefined) {
8 | 'use strict';
9 |
10 | /**
11 | * Creates the thumbs plugin.
12 | * @class The thumbs Plugin
13 | * @param {Owl} carousel - The Owl Carousel
14 | */
15 | var Thumbs = function (carousel) {
16 |
17 |
18 | /**
19 | * Reference to the core.
20 | * @protected
21 | * @type {Owl}
22 | */
23 | this.owl = carousel;
24 |
25 |
26 | /**
27 | * All DOM elements for thumbnails
28 | * @protected
29 | * @type {Object}
30 | */
31 | this._thumbcontent = [];
32 |
33 |
34 | /**
35 | * Instance identiefier
36 | * @type {number}
37 | * @private
38 | */
39 | this._identifier = 0;
40 |
41 |
42 | /**
43 | * Return current item regardless of clones
44 | * @protected
45 | * @type {Object}
46 | */
47 | this.owl_currentitem = this.owl.options.startPosition;
48 |
49 |
50 | /**
51 | * The carousel element.
52 | * @type {jQuery}
53 | */
54 | this.$element = this.owl.$element;
55 |
56 |
57 | /**
58 | * All event handlers.
59 | * @protected
60 | * @type {Object}
61 | */
62 | this._handlers = {
63 | 'prepared.owl.carousel': $.proxy(function (e) {
64 | if (e.namespace && this.owl.options.thumbs && !this.owl.options.thumbImage && !this.owl.options.thumbsPrerendered && !this.owl.options.thumbImage) {
65 | if ($(e.content).find('[data-thumb]').attr('data-thumb') !== undefined) {
66 | this._thumbcontent.push($(e.content).find('[data-thumb]').attr('data-thumb'));
67 | }
68 | } else if (e.namespace && this.owl.options.thumbs && this.owl.options.thumbImage) {
69 | var innerImage = $(e.content).find('img');
70 | this._thumbcontent.push(innerImage);
71 | }
72 | }, this),
73 |
74 | 'initialized.owl.carousel': $.proxy(function (e) {
75 | if (e.namespace && this.owl.options.thumbs) {
76 | this.render();
77 | this.listen();
78 | this._identifier = this.owl.$element.data('slider-id');
79 | this.setActive();
80 | }
81 | }, this),
82 |
83 | 'changed.owl.carousel': $.proxy(function (e) {
84 | if (e.namespace && e.property.name === 'position' && this.owl.options.thumbs) {
85 | this._identifier = this.owl.$element.data('slider-id');
86 | this.setActive();
87 | }
88 | }, this)
89 | };
90 |
91 | // set default options
92 | this.owl.options = $.extend({}, Thumbs.Defaults, this.owl.options);
93 |
94 | // register the event handlers
95 | this.owl.$element.on(this._handlers);
96 | };
97 |
98 |
99 | /**
100 | * Default options.
101 | * @public
102 | */
103 | Thumbs.Defaults = {
104 | thumbs: true,
105 | thumbImage: false,
106 | thumbContainerClass: 'owl-thumbs',
107 | thumbItemClass: 'owl-thumb-item',
108 | moveThumbsInside: false
109 | };
110 |
111 |
112 | /**
113 | * Listen for thumbnail click
114 | * @protected
115 | */
116 | Thumbs.prototype.listen = function () {
117 |
118 | //set default options
119 | var options = this.owl.options;
120 |
121 | if (options.thumbsPrerendered) {
122 | this._thumbcontent._thumbcontainer = $('.' + options.thumbContainerClass);
123 | }
124 |
125 | //check what thumbitem has been clicked and move slider to that item
126 | $(this._thumbcontent._thumbcontainer).on('click', this._thumbcontent._thumbcontainer.children(), $.proxy(function (e) {
127 |
128 | // find relative slider
129 | this._identifier = $(e.target).closest('.' + options.thumbContainerClass).data('slider-id');
130 |
131 | // get index of clicked thumbnail
132 | var index = $(e.target).parent().is(this._thumbcontent._thumbcontainer) ? $(e.target).index() : $(e.target).closest('.'+options.thumbItemClass).index();
133 |
134 | if (options.thumbsPrerendered) {
135 | // slide to slide :)
136 | $('[data-slider-id=' + this._identifier + ']').trigger('to.owl.carousel', [index, options.dotsSpeed, true]);
137 | } else {
138 | this.owl.to(index, options.dotsSpeed);
139 | }
140 |
141 | e.preventDefault();
142 | }, this));
143 | };
144 |
145 |
146 | /**
147 | * Builds thumbnails
148 | * @protected
149 | */
150 | Thumbs.prototype.render = function () {
151 |
152 | //set default options
153 | var options = this.owl.options;
154 |
155 | //create thumbcontainer
156 | if (!options.thumbsPrerendered) {
157 | this._thumbcontent._thumbcontainer = $('').addClass(options.thumbContainerClass).appendTo(this.$element);
158 | } else {
159 | this._thumbcontent._thumbcontainer = $('.' + options.thumbContainerClass + '');
160 | if(options.moveThumbsInside){
161 | this._thumbcontent._thumbcontainer.appendTo(this.$element);
162 | }
163 | }
164 |
165 | //create thumb items
166 | var i;
167 | if (!options.thumbImage) {
168 | for (i = 0; i < this._thumbcontent.length; ++i) {
169 | this._thumbcontent._thumbcontainer.append('
');
170 | }
171 | } else {
172 | for (i = 0; i < this._thumbcontent.length; ++i) {
173 | this._thumbcontent._thumbcontainer.append('
');
174 | }
175 | }
176 | };
177 |
178 |
179 | /**
180 | * Updates active class on thumbnails
181 | * @protected
182 | */
183 | Thumbs.prototype.setActive = function () {
184 |
185 | // get startslide
186 | this.owl_currentitem = this.owl._current - (this.owl._clones.length / 2);
187 | if (this.owl_currentitem === this.owl._items.length) {
188 | this.owl_currentitem = 0;
189 | }
190 |
191 | //set default options
192 | var options = this.owl.options;
193 |
194 | // set relative thumbnail container
195 | var thumbContainer = options.thumbsPrerendered ? $('.' + options.thumbContainerClass + '[data-slider-id="' + this._identifier + '"]') : this._thumbcontent._thumbcontainer;
196 | thumbContainer.children().filter('.active').removeClass('active');
197 | thumbContainer.children().eq(this.owl_currentitem).addClass('active');
198 | };
199 |
200 |
201 | /**
202 | * Destroys the plugin.
203 | * @public
204 | */
205 | Thumbs.prototype.destroy = function () {
206 | var handler, property;
207 | for (handler in this._handlers) {
208 | this.owl.$element.off(handler, this._handlers[handler]);
209 | }
210 | for (property in Object.getOwnPropertyNames(this)) {
211 | typeof this[property] !== 'function' && (this[property] = null);
212 | }
213 | };
214 |
215 | $.fn.owlCarousel.Constructor.Plugins.Thumbs = Thumbs;
216 |
217 | })(window.Zepto || window.jQuery, window, document);
--------------------------------------------------------------------------------