创建2个可以相互通信的jquery插件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建2个可以相互通信的jquery插件相关的知识,希望对你有一定的参考价值。
我现在的头很乱。我想创建2个jquery插件:
- 一个标签插件
- 一个滑块插件。
此插件必须相互通信,例如,如果单击选项卡,此选项卡将激活相关滑块中的正确索引。如果我点击幻灯片,这也会激活正确的选项卡。
我开始为此创建事件监听器和触发器,当单击我的选项卡时,触发事件'tabChanged',并且在我的滑块插件中我正在收听它。但是这里有麻烦,我的滑块可以在我的标签之前加载,所以听众没有正确连接......
我这次尝试在文档上触发另一个事件,称为“tabsLoaded”并等待该响应,它可以工作,但它开始有点令人困惑。
我想知道是否有人有更好的解决方案吗?选项卡和滑块也可以作为独立工作,也可以只使用没有滑块关联的选项卡。
非常感谢 !
这是我的标签插件:
(function($) {
let pluginName = 'Tabs';
function Tabs(element, options) {
let settings = {};
this.element = element;
this.$element = $(this.element);
this.settings = $.extend({}, settings, options);
this.children = null;
this.activeTabIndex = 0;
this.nbTabs = 0;
this.init();
}
$.extend(Tabs.prototype, {
init: function() {
this.children = this.$element.children();
this.nbTabs = this.children.length;
// Listeners
this.children.on('click', {
tabs: this
}, this.onTabChange); // Click on a tab
$(this).on('tabChange', this.setActive);
// On Init, active the first tab
if (this.children && this.nbTabs > 0) {
$(this).trigger({
type: 'tabChange',
tab: this.children.first().index(),
});
}
$(document).trigger({
type: 'tabLoaded',
tabs: this,
});
},
setActive: function(event) {
this.activeTabIndex = event.tab;
this.children.eq(this.activeTabIndex).addClass('is-active');
},
onTabChange: function(event) {
event.preventDefault();
const tabs = event.data.tabs;
// Reset active classes
tabs.children.removeClass('is-active');
// Launch changeTab
$(tabs).trigger({
type: 'tabChange',
tab: tabs.children.index(event.currentTarget),
});
}
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, pluginName)) {
$.data(this, pluginName, new Tabs(this, options));
}
});
};
})(jQuery);
jQuery(document).ready(function($) {
$('.js-tabs').Tabs();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
这是我的滑块插件监听标签:
(function($) {
let pluginName = 'Slider';
function Slider(element, options) {
let settings = {};
this.element = element;
this.$element = $(this.element);
this.settings = $.extend({}, settings, options);
this.id = null;
this.tabs = null;
this.children = null;
this.activeSlideIndex = 0;
this.nbSlides = 0;
this.init();
}
$.extend(Slider.prototype, {
init: function() {
this.id = this.$element.attr('id');
this.children = this.$element.children();
this.nbSlides = this.children.length;
// Listeners
// Click on slide
this.children.on('click', {
slider: this
}, this.onSlideChange);
// On slide change
$(this).on('slideChange', {
slider: this
}, this.onSlideChange);
$(this).on('change', this.update);
// On Init, active the first tab
if (this.children && this.nbSlides > 0) {
$(this).trigger({
type: 'slideChange',
slide: this.children.first().index(),
});
}
$(document).trigger({
type: 'sliderLoaded',
slider: this,
});
},
update: function() {
// if Slider has an associated Tabs
if (this.tabs) {
$(this.tabs).on('tabChange', {
slider: this
}, this.onTabChange);
}
},
onSlideChange: function(event) {
event.preventDefault();
const slider = event.data.slider;
const slide = event.slide;
// Reset active classes
slider.children.removeClass('is-active');
slider.activeSlideIndex = slide ? slide : event.currentTarget;
console.log(slider.activeSlideIndex);
slider.children.eq(slider.activeSlideIndex).addClass('is-active');
},
// TABS
onTabChange: function(event) {
const slider = event.data.slider;
const tabIndex = event.tab;
if ($(slider.children).eq(tabIndex).length >= 0) {
$(slider).trigger({
type: 'slideChange',
slide: tabIndex,
});
}
}
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, pluginName)) {
$.data(this, pluginName, new Slider(this, options));
}
});
};
})(jQuery);
jQuery(document).ready(function($) {
$('.js-slider').Slider();
});
// On Tabs loaded, insert it into slider
jQuery(document).on('tabLoaded', function(event) {
const tabs = event.tabs;
const sliderId = jQuery(tabs.element).data('slider-id');
if (jQuery('#' + sliderId).first().data('Slider')) {
const slider = jQuery('#' + sliderId).first().data('Slider');
slider.tabs = tabs;
slider.update();
}
});
答案
我跟着@Anton的建议,我拆分了我的标签和滑块,它工作得很好:)
- 首先,我从插件的文件中删除了插件的插件。
- 然后我把每个inits放到我称为“app.js”的另一个文件中
我的App.js看起来像这样:
jQuery(document).ready(function ($) {
let $sliders = $('.js-slider').Slider();
let $tabs = $('.js-tabs').Tabs();
$sliders.on('slideChanged', function (event) {
const sliderId = $(this).attr('id');
const slide = event.slide;
$tabs.filter('[data-slider-id=' + sliderId + ']').data('Tabs').select(slide);
});
$tabs.on('tabChanged', function (event) {
const sliderId = $(this).data('slider-id');
const tab = event.tab;
$sliders.filter('#' + sliderId).data('Slider').select(tab);
});
});
以上是关于创建2个可以相互通信的jquery插件的主要内容,如果未能解决你的问题,请参考以下文章