Что не так с плагином
Учусь писать свои плагины для 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, время: 18:48. |