Что не так с плагином
Учусь писать свои плагины для Jquery. В частности слайдер. Вот что пока есть:
(function($){ // настройки со значением по умолчанию var defaults = { speed: 500 }; // наши будущие публичные методы var methods = { xDown: null, yDown: null, // инициализация плагина init: function(options, args ) { // настройки, будут индивидуальными при каждом запуске var options = $.extend({}, defaults, options); // инициализируем лишь единожды if (!this.data('sSlider')) { this.data('sSlider', options); // добавим событий var slider = this; $(document) .on('click', '*[data-direction]', function(e){ e.preventDefault(); methods.move( this, $(this).data('direction'), options ); }); } return this; }, // контейнер со слайдами move: function( slider, direction, options ) { var slider = $(slider), block = slider.find('*[data-element="box"]'), items = block.children(), first = items.eq(0); last = items.eq(-1); console.log( methods.init ); if( first.is( ':animated' ) ) { return; } items.stop(true, true); if ( direction === 'prev' ) { first.animate({ marginLeft: 0 - first.outerWidth() }, options.speed, function() { first.css('margin-left', 0) .appendTo( first.parent() ); }); } else { last.prependTo(last.parent()) .css('margin-left','-'+last.outerWidth()+'px') .animate({marginLeft:0}, options.speed); } }, }; $.fn.sSlider = function(method){ // немного магии console.log(this); if ( methods[method] ) { // если запрашиваемый метод существует, мы его вызываем // все параметры, кроме имени метода прийдут в метод // this так же перекочует в метод return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { // если первым параметром идет объект, либо совсем пусто // выполняем метод init console.log( this ); return methods.init.apply( this, arguments ); } else { // если ничего не получилось $.error('Method "' + method + '" not found'); } }; })(jQuery); $('.glider').sSlider(); Застопорился в методе move. Я пытаюсь обратиться к родительскому блоку .glider, который заявлен в $('.glider').sSlider(); Но в методе move: function( slider, direction, options ), параметре slider какая-то дичь. Я не могу получить к нему доступ, чтобы обратиться к дочерним. Надеюсь на любую помощь. |
Янковиц,
строка 23 methods.move( |
Тот же самый результат. В строках 30 и 31, результат null
(function($){ // настройки со значением по умолчанию var defaults = { speed: 500 }; // наши будущие публичные методы var methods = { xDown: null, yDown: null, // инициализация плагина init: function(options, args ) { // настройки, будут индивидуальными при каждом запуске var options = $.extend({}, defaults, options); // инициализируем лишь единожды if (!this.data('sSlider')) { this.data('sSlider', options); // добавим событий var slider = this; $(document) .on('click', '*[data-direction]', function(e){ e.preventDefault(); methods.move( slider, $(this).data('direction'), options ); }); } return this; }, // двигаем слайдер move: function( slider, direction, options ) { console.log( $(slider).width() ); console.log( slider.width() ); var block = slider.find('*[data-element="box"]'), items = block.children(), first = items.eq(0); last = items.eq(-1); if( first.is( ':animated' ) ) { return; } items.stop(true, true); if ( direction === 'prev' ) { first.animate({ marginLeft: 0 - first.outerWidth() }, options.speed, function() { first.css('margin-left', 0) .appendTo( first.parent() ); }); } else { last.prependTo(last.parent()) .css('margin-left','-'+last.outerWidth()+'px') .animate({marginLeft:0}, options.speed); } }, }; $.fn.sSlider = function(method){ if ( methods[method] ) { // если запрашиваемый метод существует, мы его вызываем // все параметры, кроме имени метода прийдут в метод // this так же перекочует в метод return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { // если первым параметром идет объект, либо совсем пусто // выполняем метод init return methods.init.apply( this, arguments ); } else { // если ничего не получилось $.error('Method "' + method + '" not found'); } }; })(jQuery); $('.glider').sSlider(); |
Янковиц,
вы строку 19 проверьте, что там у вас |
n.fn.init [prevObject: n.fn.init(1), context: document, selector: ".glider"] length: 0 prevObject: n.fn.init [document, context: document] context: documentDOMStringList, origin: "file://", protocol: "file:", host: "", …} implementation: DOMImplementation {} compatMode: "CSS1Compat" characterSet: "UTF-8" charset: "UTF-8" inputEncoding: "UTF-8" contentType: "text/html" doctype: html documentElement: html xmlEncoding: null xmlVersion: null xmlStandalone: false domain: "" referrer: "" cookie: "" lastModified: "04/23/2020 18:44:47" readyState: "complete" title: "CodePen - Just another CSS UI" dir: "" body: body head: head images: HTMLCollection(5) [img, img, img, img, img] embeds: HTMLCollection [] plugins: HTMLCollection [] links: HTMLCollection(13) [a, a, a, a, a, a, a, a, a, a, a, a, a] forms: HTMLCollection [] scripts: HTMLCollection(2) [script, script] currentScript: null defaultView: Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …} designMode: "off" onreadystatechange: null anchors: HTMLCollection [] applets: HTMLCollection [] fgColor: "" linkColor: "" vlinkColor: "" alinkColor: "" bgColor: "" all: HTMLAllCollection(131) [html, head, meta, title, script, link#daria-css, script, body, div.glider.container, div.glider__post.padt, div.glider__post_count, div.glider__share, div.slider__share_item.facebook, div.slider__share_item.twitter, div.slider__share_item.pinterest, div.slider__share_item.vk, img, div.glider__post_item, img, div.glider__post_data, h2, a, p, div.glider__arrow, span.glider__arrow_prev, svg, path, span.glider__arrow_next, svg, path, div.glider__box.padt, div.glider__box_item, div.block_title, h2.padr, img, span.block_title_all.padl, a, svg, path, span, div.glider__item, div.post__data, span.post__data_item, i.date, span.post__data_item, i.views, h2, a, div.glider__item, div.post__data, span.post__data_item, i.date, span.post__data_item, i.views, h2, a, div.glider__item, div.post__data, span.post__data_item, i.date, span.post__data_item, i.views, h2, a, div.glider__box_item, div.block_title, h2.padr, img, span.block_title_all.padl, a, svg, path, span, div.glider__item, div.post__data, span.post__data_item, i.date, span.post__data_item, i.views, h2, a, div.glider__item, div.post__data, span.post__data_item, i.date, span.post__data_item, i.views, h2, a, div.glider__item, div.post__data, span.post__data_item, i.date, span.post__data_item, i.views, h2, a, div.glider__box_item, div.block_title, h2.padr, …] scrollingElement: html onpointerlockchange: null onpointerlockerror: null hidden: false visibilityState: "visible" wasDiscarded: false webkitVisibilityState: "visible" webkitHidden: false onbeforecopy: null onbeforecut: null onbeforepaste: null onfreeze: null onresume: null onsearch: null onsecuritypolicyviolation: null onvisibilitychange: null fonts: FontFaceSet {onloading: null, onloadingdone: null, onloadingerror: null, ready: Promise, status: "loaded", …} oncopy: null oncut: null onpaste: null activeElement: body styleSheets: StyleSheetList {0: CSSStyleSheet, 1: CSSStyleSheet, length: 2} pointerLockElement: null fullscreenElement: null adoptedStyleSheets: [] onabort: null onblur: null oncancel: null oncanplay: null oncanplaythrough: null onchange: null onclick: null onclose: null oncontextmenu: null oncuechange: null ondblclick: null ondrag: null ondragend: null ondragenter: null ondragleave: null ondragover: null ondragstart: null ondrop: null ondurationchange: null onemptied: null onended: null onerror: null onfocus: null onformdata: null oninput: null oninvalid: null onkeydown: null onkeypress: null onkeyup: null onload: null onloadeddata: null onloadedmetadata: null onloadstart: null onmousedown: null onmouseenter: null onmouseleave: null onmousemove: null onmouseout: null onmouseover: null onmouseup: null onmousewheel: null onoperadetachedviewchange: null onoperadetachedviewcontrol: null onpause: null onplay: null onplaying: null onprogress: null onratechange: null onreset: null onresize: null onscroll: null onseeked: null onseeking: null onselect: null onstalled: null onsubmit: null onsuspend: null ontimeupdate: null ontoggle: null onvolumechange: null onwaiting: null onwheel: null onauxclick: null ongotpointercapture: null onlostpointercapture: null onpointerdown: null onpointermove: null onpointerup: null onpointercancel: null onpointerover: null onpointerout: null onpointerenter: null onpointerleave: null onselectstart: null onselectionchange: null onanimationend: null onanimationiteration: null onanimationstart: null ontransitionend: null children: HTMLCollection [html] firstElementChild: html lastElementChild: html childElementCount: 1 fullscreenEnabled: true fullscreen: false onfullscreenchange: null onfullscreenerror: null webkitIsFullScreen: false webkitCurrentFullScreenElement: null webkitFullscreenEnabled: true webkitFullscreenElement: null onwebkitfullscreenchange: null onwebkitfullscreenerror: null rootElement: null featurePolicy: FeaturePolicy {} onpointerrawupdate: null pictureInPictureElement: null pictureInPictureEnabled: true nodeType: 9 nodeName: "#document" isConnected: true ownerDocument: null parentNode: null parentElement: null childNodes: NodeList(2) [html, html] firstChild: html lastChild: html previousSibling: null nextSibling: null nodeValue: null textContent: null |
Янковиц,
и лучше не загадка из куска кода, а минимальный макет, пусть и не рабочий. |
То есть, как я понимаю, всё null
Это 19 строка |
Янковиц,
попробуйте так $(function() { $('.glider').sSlider(); }); |
Заработало!
|
Интересно, в чём причина?
|
Цитата:
на странице ещё не было элемента, jquery продолжает работать, кто - то считает что это минус jquery, и всё должно было рухнуть , кто - то что это плюс что ничего не случилось. :) |
Небольшое дополнение. Добавил в плагин callback функции moveStart и moveEnd.
(function($){ // настройки со значением по умолчанию var defaults = { speed: 500, moveStart: function() {}, moveEnd: function() {}, }; // наши будущие публичные методы var methods = { xDown: null, yDown: null, // инициализация плагина init: function( options, args ) { // настройки, будут индивидуальными при каждом запуске var options = $.extend({}, defaults, options); // инициализируем лишь единожды if (!this.data('sSlider')) { this.data('sSlider', options); // добавим событий var slider = this, child_class = slider.find('*[data-element="box"]').children().eq(0).attr('class'); $(document) .on('mousedown touchend', '*[data-direction]', function(e){ methods.move( slider, $(this).data('direction'), options ); }) } return this; }, // двигаем слайдер move: function( slider, direction, options ) { var block = slider.find('*[data-element="box"]'), items = block.children(), first = items.eq(0), last = items.eq(-1); if( first.is( ':animated' ) ) { return; } items.stop(true, true); options.moveStart.call( slider, direction ); if ( direction === 'prev' ) { first.animate({ marginLeft: 0 - first.outerWidth() }, options.speed, function() { first.css('margin-left', 0) .appendTo( first.parent() ); }); } else { last.prependTo(last.parent()) .css('margin-left','-'+last.outerWidth()+'px') .animate({marginLeft:0}, options.speed); } setTimeout(function () { options.moveEnd.call( slider, direction ); }, options.speed); }, }; $.fn.sSlider = function(method){ if ( methods[method] ) { // если запрашиваемый метод существует, мы его вызываем // все параметры, кроме имени метода прийдут в метод // this так же перекочует в метод return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { // если первым параметром идет объект, либо совсем пусто // выполняем метод init return methods.init.apply( this, arguments ); } else { // если ничего не получилось $.error('Method "' + method + '" not found'); } }; })(jQuery); Затем вызываю слайдер: $(function() { $('.glider').sSlider({ moveStart: function( slider, direction ) { console.log( slider ); console.log( direction ); }, }); }); При этом console.log из строки 04 показывает "prev" или "next", а в строке 05 "undefined". Хотя сначала я ожидал увидеть DOM элемент $('.glider'), а затем направление direction. Что я делаю не так? |
Янковиц,
$(function() { $('.glider').sSlider({ moveStart: function(direction ) { console.log( this ); console.log( direction ); }, }); }); |
Янковиц,
или так options.moveStart.call( null , slider, direction ); или так options.moveStart.call( slider , slider, direction ); для moveStart: function( slider, direction ) |
Янковиц,
Метод call func.call(context, arg1, arg2, ...) сначала идёт контекст (this), а потом уже аргументы. |
Спасибо большое
|
Стало необходимо запускать процессы более 1 раза на странице. Я понимаю, что нужно использовать что-то вроде этого:
return this.each(function() { var $this = $(this); }); Но совершенно не знаю, в какой момент |
Янковиц,
вместо строк 18 - 31 |
На строку 20 ругается: index.html:20 Uncaught TypeError: this.data is not a function
|
Цитата:
Цитата:
|
Янковиц,
убрал лишнее ... // инициализация плагина init: function f(options, args) { var options = $.extend({}, defaults, options); return this.each(function() { var $this = $(this); if (!$this.data("sSlider")) { $this.data("sSlider", options); $("[data-direction]", $this).on("mousedown touchend", function(e) { methods.move($this, $(this).data("direction"), options); }); } }); }, |
Подскажите, как можно получить селектор .glider объявленный в
$('.glider').sSlider(); ? |
Янковиц,
сейчас только указав в options. |
Янковиц,
может сделать без jquery? |
Часовой пояс GMT +3, время: 08:05. |