Javascript类实例化
我创建了一个简单的javascript类来包装 实例化此类多个实例的最佳方法是什么? 我现在看到了下面的示例,它搜索DOM并创建组件的新类实例(如果找到)。我怀疑我的项目会增长一点,而这个“根”文件可能是因为有点臃肿/混乱。有没有更好的组织方式 我将为进一步的功能添加额外的类,因此尝试尽早找到最佳方法 main.jsJavascript类实例化,javascript,ecmascript-6,es6-class,Javascript,Ecmascript 6,Es6 Class,我创建了一个简单的javascript类来包装 实例化此类多个实例的最佳方法是什么? 我现在看到了下面的示例,它搜索DOM并创建组件的新类实例(如果找到)。我怀疑我的项目会增长一点,而这个“根”文件可能是因为有点臃肿/混乱。有没有更好的组织方式 我将为进一步的功能添加额外的类,因此尝试尽早找到最佳方法 main.js import Carousel from '../app/assets/javascripts/carousel/Carousel'; var carouselElements
import Carousel from '../app/assets/javascripts/carousel/Carousel';
var carouselElements = Array.from(document.getElementsByClassName('slick-media'));
if (carouselElements) {
carouselElements.map(function (element) {
new Carousel(element, true, {xs: 6, md: 6, lg: 6 });
});
}
export default class Carousel {
constructor(element, variableWidth = false, breakpoint) {
this.element = element;
this.variableWidth = variableWidth;
this.breakpoint = breakpoint
this._init(element);
/* Bind methods */
this._init = this._init.bind(this);
}
_init() {
this._instantiateSlick(this.element);
}
_instantiateSlick(element) {
$(element).slick({
lazyLoad: 'ondemand',
slidesToScroll: 1,
adaptiveHeight: true,
useTransform: true,
/* Default over lg breakpoint */
slidesToShow: this.breakpoint.lg,
/* Allow slick to calculate widths */
variableWidth: this.variableWidth,
responsive: [
{
breakpoint: 1199,
settings: {
slidesToShow: this.breakpoint.lg,
slidesToScroll: 1,
infinite: true
}
},
{
breakpoint: 991,
settings: {
slidesToShow: this.breakpoint.md,
slidesToScroll: 1,
infinite: true
}
},
{
breakpoint: 480,
settings: {
slidesToShow: this.breakpoint.xs,
slidesToScroll: 1,
infinite: true
}
}]
});
}
}
Carousel.js
import Carousel from '../app/assets/javascripts/carousel/Carousel';
var carouselElements = Array.from(document.getElementsByClassName('slick-media'));
if (carouselElements) {
carouselElements.map(function (element) {
new Carousel(element, true, {xs: 6, md: 6, lg: 6 });
});
}
export default class Carousel {
constructor(element, variableWidth = false, breakpoint) {
this.element = element;
this.variableWidth = variableWidth;
this.breakpoint = breakpoint
this._init(element);
/* Bind methods */
this._init = this._init.bind(this);
}
_init() {
this._instantiateSlick(this.element);
}
_instantiateSlick(element) {
$(element).slick({
lazyLoad: 'ondemand',
slidesToScroll: 1,
adaptiveHeight: true,
useTransform: true,
/* Default over lg breakpoint */
slidesToShow: this.breakpoint.lg,
/* Allow slick to calculate widths */
variableWidth: this.variableWidth,
responsive: [
{
breakpoint: 1199,
settings: {
slidesToShow: this.breakpoint.lg,
slidesToScroll: 1,
infinite: true
}
},
{
breakpoint: 991,
settings: {
slidesToShow: this.breakpoint.md,
slidesToScroll: 1,
infinite: true
}
},
{
breakpoint: 480,
settings: {
slidesToShow: this.breakpoint.xs,
slidesToScroll: 1,
infinite: true
}
}]
});
}
}
实际上,您可以将其缩短为:
Array.from(
document.getElementsByClassName('slick-media'),
node => new Carousel(node, true, {xs: 6, md: 6, lg: 6 })
);
实际上,您可以将其缩短为:
Array.from(
document.getElementsByClassName('slick-media'),
node => new Carousel(node, true, {xs: 6, md: 6, lg: 6 })
);
在我看来,用一个类来做这件事似乎太过分了。您以后永远不会访问创建的对象,因为您不会保留对它们的引用,因此它们的唯一目的似乎是立即执行一个操作:将
slick
应用于具有某些预定义配置的元素。建造完成后,它们立即变得无用
第二,当之后仍然有一个被证明是必需的参数时,为参数使用默认值不是很有用。因此,交换断点
和可变宽度
的参数位置
作为替代方案,我建议为此创建jQuery插件:
$.fn.simpleSlick = function (breakpoint, variableWidth = false) {
this.slick({
lazyLoad: 'ondemand',
slidesToScroll: 1,
adaptiveHeight: true,
useTransform: true,
/* Default over lg breakpoint */
slidesToShow: breakpoint.lg,
/* Allow slick to calculate widths */
variableWidth,
responsive: [{
breakpoint: 1199,
settings: {
slidesToShow: breakpoint.lg,
slidesToScroll: 1,
infinite: true
}
}, {
breakpoint: 991,
settings: {
slidesToShow: breakpoint.md,
slidesToScroll: 1,
infinite: true
}
}, {
breakpoint: 480,
settings: {
slidesToShow: breakpoint.xs,
slidesToScroll: 1,
infinite: true
}
}]
});
return this; // to allow chaining
};
假设slick
插件按照规则运行(即允许jQuery对象匹配多个元素),那么实际使用它就变得非常简单:
$('.slick-media').simpleSlick({xs: 6, md: 6, lg: 6 }, true);
当课程是给定的
如果应该将类的使用视为给定的,那么您仍然可以使用jQuery方式通过class
属性选择元素(因为您已经将jQuery用于slick
插件):
(但同样,在不使用结果对象的情况下应用new
,会显示错误的设计)
如果您想通过DOM元素访问这些转盘对象,那么您可以考虑使用<代码>数据< /C>方法:
$('.slick-media').each(function () {
$(this).data('carousel', new Carousel(this, true, {xs: 6, md: 6, lg: 6 }));
});
对于给定的elem
元素,您可以访问相应的Carousel
实例,如下所示:
var carousel = $(elem).data('carousel'); // Get the Carousel instance
在我看来,用一个类来做这件事似乎太过分了。您以后永远不会访问创建的对象,因为您不会保留对它们的引用,因此它们的唯一目的似乎是立即执行一个操作:将
slick
应用于具有某些预定义配置的元素。建造完成后,它们立即变得无用
第二,当之后仍然有一个被证明是必需的参数时,为参数使用默认值不是很有用。因此,交换断点
和可变宽度
的参数位置
作为替代方案,我建议为此创建jQuery插件:
$.fn.simpleSlick = function (breakpoint, variableWidth = false) {
this.slick({
lazyLoad: 'ondemand',
slidesToScroll: 1,
adaptiveHeight: true,
useTransform: true,
/* Default over lg breakpoint */
slidesToShow: breakpoint.lg,
/* Allow slick to calculate widths */
variableWidth,
responsive: [{
breakpoint: 1199,
settings: {
slidesToShow: breakpoint.lg,
slidesToScroll: 1,
infinite: true
}
}, {
breakpoint: 991,
settings: {
slidesToShow: breakpoint.md,
slidesToScroll: 1,
infinite: true
}
}, {
breakpoint: 480,
settings: {
slidesToShow: breakpoint.xs,
slidesToScroll: 1,
infinite: true
}
}]
});
return this; // to allow chaining
};
假设slick
插件按照规则运行(即允许jQuery对象匹配多个元素),那么实际使用它就变得非常简单:
$('.slick-media').simpleSlick({xs: 6, md: 6, lg: 6 }, true);
当课程是给定的
如果应该将类的使用视为给定的,那么您仍然可以使用jQuery方式通过class
属性选择元素(因为您已经将jQuery用于slick
插件):
(但同样,在不使用结果对象的情况下应用new
,会显示错误的设计)
如果您想通过DOM元素访问这些转盘对象,那么您可以考虑使用<代码>数据< /C>方法:
$('.slick-media').each(function () {
$(this).data('carousel', new Carousel(this, true, {xs: 6, md: 6, lg: 6 }));
});
对于给定的elem
元素,您可以访问相应的Carousel
实例,如下所示:
var carousel = $(elem).data('carousel'); // Get the Carousel instance
您已经澄清,您的问题是关于如何使用类的(例如,
main.js
)中的代码:
这是关于main.js文件,以及它实例化多个实例的方式。这是最好的方法吗
有几个细节需要挑:
map
创建一个数组,该数组使用未定义的填充,并且从不使用。不使用返回的数组时,不要使用map
;使用以下任何一种的forEach
;像getElementsByClassName
这样的方法总是返回NodeList
或HTMLCollection
(取决于方法),即使它是空的
getElementsByClassName
(因为它可以惊人地快;注意,它在像IE8这样的过时浏览器上并不存在):
注意使用Array.prototype.forEach
为我们做循环,因为它可以在任何类似数组的东西上工作。这将适用于任何现代浏览器和IE9-IE11
如果您不介意非常小的开销,您可以使用querySelectorAll
(甚至在IE8上也存在)来获得匹配所有类的列表,而不必单独处理每个类:
import Carousel from '../app/assets/javascripts/carousel/Carousel';
document.querySelectorAll('.slick-media, .another-class, .some-further-class').forEach(element => {
new Carousel(element, true, {xs: 6, md: 6, lg: 6 });
});
我没有在那里使用Array.prototype.forEach
,因为NodeList
有自己的forEach
做同样的事情。如果需要支持IE9-IE11,则需要polyfill,这很简单:
if (typeof NodeList !== "undefined" &&
NodeList.prototype &&
!NodeList.prototype.forEach) {
// Surprisingly, the standard `NodeList.prototype.forEach` is enumerable (as well as
// writable and configurable) so we can just assign rather than using `defineProperty`
NodeList.prototype.forEach = Array.prototype.forEach;
}
当然,如果您愿意的话,也可以使用Array.prototype.forEach
来代替getElementsByClassName
在最新的Chrome和Firefox等尖端环境中,您可以这样做:
import Carousel from '../app/assets/javascripts/carousel/Carousel';
for (const element of document.querySelectorAll('.slick-media, .another-class, .some-further-class')) {
new Carousel(element, true, {xs: 6, md: 6, lg: 6 });
}
…这依赖于
节点列表
是可编辑的。我没有在上面这样做,因为在NodeList
上多填充迭代器比在不知道您正在使用什么transpiler(如果您正在使用transpiler)的情况下多填充forEach
更难。您已经澄清了您的问题是关于如何使用类(例如,代码)