javascript - Calling prototype method inside function not working -
trying create 1 gallery class using javascript , jquery.
i have prototype function gallery class, when try access functions inside class shows error.
uncaught typeerror: gallery.start not function my jsfiddle link
here javascript:
/** * * @param options should object of following * options.images array of gallery images url * options.start slide starting point * options.autoplay option false default * */ function gallery(options) { var _this = this; var galleryoptions = options; function randomstring(len, charset) { var ranstring = ''; var randompoz; charset = charset || 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789'; (var = 0; < len; i++) { randompoz = math.floor(math.random() * charset.length); ranstring = ranstring + charset.substring(randompoz, randompoz + 1); } return ranstring; } function addthumbnail(imgsrc) { return '<li class="thumbnail__list"><img src="' + imgsrc + '" class="thumbnail__list-img" /></li>'; } function renderthumbnail(imgarr) { var html = []; if (imgarr) { $.each(imgarr, function(i, v) { html.push(addthumbnail(v)); }); } return '<ul class="gallery__thumbnail__container">' + html.join('') + '</ul>'; } function getplaceholder() { return 'dummy.jpg'; } function disablenext(thisobj) { thisobj.galleryelement.find('.next').addclass('disabled'); } function disableprev(thisobj) { thisobj.galleryelement.find('.prev').addclass('disabled'); } function enablenext(thisobj) { thisobj.galleryelement.find('.next').removeclass('disabled'); } function enableprev(thisobj) { thisobj.galleryelement.find('.prev').removeclass('disabled'); } function toggleprevnext(self) { if (self._opt.currindex === (self._opt.imageslength)) { disablenext(self); } else { enablenext(self); } if ((self._opt.currindex - 1) === 0) { disableprev(self); } else { enableprev(self); } } function controls() { var html = []; html.push('<div class="prev sz-icon-arrow-left"></div>'); html.push('<div class="next sz-icon-arrow-right"></div>'); return '<div class="gallery__controls">' + html.join('') + '</div>'; } function bindclickevents(galleryelement) { galleryelement.on('click', '.start', function() { _this.start(); }); galleryelement.find('.stop').on('click', function() { _this.stop(); }); galleryelement.find('.prev').on('click', function() { _this.prev(); }); galleryelement.find('.next').on('click', function() { _this.next(); }); galleryelement.find('.thumbnail__list').on('click', function() { _this.goto(number($(this).index()) + 1); }); } function checkoptions(option) { var opt = option; opt.images = (opt.images.length) ? opt.images : getplaceholder(); opt.thumbnail = (opt.thumbnail) ? true : false; opt.fullscreen = (opt.fullscreen) ? true : false; opt.container = (opt.fullscreen) ? 'body' : opt.container; opt.container = (opt.container) ? opt.container : 'body'; opt.autoplay = (opt.autoplay) ? true : false; opt.start = (opt.start && opt.start <= number(opt.images.length)) ? opt.start : 1; return opt; } gallery.init = function() { var html; _this._opt = checkoptions(galleryoptions); _this._opt.imageslength = number(_this._opt.images.length); _this._opt.currindex = number(_this._opt.start); _this._opt.elementname = 'gallery--' + randomstring(5, 'szgallery'); if (_this._opt.fullscreen) { html = '<div class="pop-up__model ' + _this._opt.elementname + '">' + '<div class="pop-up__model-table">' + '<div class="pop-up__model-cell">' + '<div class="gallery"><div class="pop-up__model-content">' + '<div class="gallery__inner-wrapper"></div>' + '</div></div>' + '</div></div>' + '</div>'; $(_this._opt.container).append('', html); if (_this._opt.thumbnail) { $('.pop-up__model-content').append('', '<div class="thumbnail__list-wrapper">' + renderthumbnail(options.images) + '</div>').append('', controls()); } } else { $(_this._opt.container).append('', '<div class="gallery gallery--hidden ' + _this._opt.elementname + '"></div>'); } _this.galleryelement = $('.' + _this._opt.elementname); if (_this._opt.fullscreen) { _this.galleryelement.find('.gallery__inner-wrapper').append('', '<div class="gallery__img-holder">' + '<img class="gallery__img-preview" src="' + _this._opt.images[_this._opt.start - 1] + '"/>' + '</div>'); } else { _this.galleryelement.append('', '<div class="gallery__img-holder">' + '<img class="gallery__img-preview" src="' + _this._opt.images[_this._opt.start - 1] + '"/>' + '</div>'); } if (_this._opt.thumbnail) { _this.galleryelement.append('', renderthumbnail(options.images)).append(controls()); } else { _this.galleryelement.append('', controls()); } if (_this._opt.autoplay) { gallery.start(); } bindclickevents(_this.galleryelement); }; gallery.prototype = { start: function() { _this.goto(_this._opt.currindex); _this.galleryelement.removeclass('gallery--hidden'); console.log('started', _this._opt); if (_this._opt.fullscreen) { $('.pop-up__model').addclass('is_visible'); } }, stop: function() { _this.galleryelement.addclass('gallery--hidden'); }, next: function() { if (_this._opt.currindex <= (_this._opt.imageslength - 1)) { _this._opt.currindex++; _this.goto(_this._opt.currindex); } }, prev: function() { if ((_this._opt.currindex - 1) !== 0) { _this._opt.currindex--; _this.goto(_this._opt.currindex); } }, goto: function(imgno) { var thumbnail; _this._opt.currindex = number(imgno); if (_this._opt.images[imgno - 1]) { _this.galleryelement.find('.gallery__img-preview').attr('src', _this._opt.images[imgno - 1]); } if (_this._opt.thumbnail) { thumbnail = _this.galleryelement.find('.thumbnail__list'); thumbnail.removeclass('active'); thumbnail.eq(imgno - 1).addclass('active'); } toggleprevnext(_this); }, destroy: function() { console.log('destroyed'); } }; return gallery; } var imgarr = ['images/placeholder-1.png', 'images/placeholder-2.png', 'images/placeholder-3.jpg', 'images/placeholder-4.jpg']; var hotelphotosgallery = new gallery({ images: imgarr, autoplay: true, container: '.photo-list' }); hotelphotosgallery.init();
after looking bit @ code, found problem:
if (_this._opt.autoplay) { gallery.start(); // method doesn't exist on non instantiated object } you trying call method on function itself, not method on prototype of instance of function (instantiated using new).
however, prototype methods won't available on non-instantiated items because this in function gets attached global object default. when using new, this becomes new object , gets implicitly returned function, creating new instance. more using function constructors
generally, fixed using context (i.e. this) instead of function name:
if (_this._opt.autoplay) { this.start(); // use context of instantiated gallery } in particular case however, re-defining prototype:
gallery.prototype = { ... } // overwriting prototype object instead of using 1 js engine prepared , add methods on it:
// add methods directly on prototype gallery.prototype.method1 = // ... gallery.prototype.method2 = // ... this way potentially unsafe since end removing else existed in prototype before re-defined it.
if not concerned , keep code way is, can access method explicitly calling prototype:
if (_this._opt.autoplay) { gallery.prototype.start(); // explicitly call prototype, since defined }
Comments
Post a Comment