一个javascript对象的多个实例,而不覆盖配置选项

Multiple instances of a javascript object without overiding config options

本文关键字:覆盖 配置 选项 实例 对象 javascript 一个      更新时间:2023-09-26

我用滚动文本的函数构建了这个对象,但当我试图将一个实例添加到另一个元素时,以前的实例会被新实例的配置选项覆盖。

下面是jsfiddle的一个例子,在顶部动画完成文本速度并覆盖所有其他配置选项之后。

HTML代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Notes</title>
    <script src="jquery-2.1.js"></script>
</head>
<body style="margin: 0 auto;">
    <div class="scroll">
        <div class="scrollContainer">
            <div class="scrollText"></div>
        </div>
    </div>
    <div>
        <div>
            <div id="me"></div>
        </div>
    </div>
    <div>
        <div>
            <div id="try">I'll overwrite everything!</div>
        </div>
    </div>
    <script src="scroll.js"></script>
</body>
</html>

JavaScript/jQuery代码:

$(document).ready(function () {
    $(function () {
        var scroll = [];
        scroll = {
            config: {
                text: 'hello everybody',
                speed: 15000,
                container: $('.scrollText'),
                width: 250,
                parent: $('.scrollContainer'),
                parentContainer: $('.scroll'),
                textWidth: 0,
                totalWidth: 0
            },
            init: function (config) {
                $.extend(this.config, config);
                var self = this,
                    selfC = self.config,
                    selfE = selfC.container;
                console.log(selfE);
                selfE.html(scroll.config.text.trim());
                selfE.css({
                    display: 'inline-block'
                })
                selfC.textWidth = scroll.config.container.width();
                //console.log(scroll.config.textWidth);
                selfE.css({
                    width: selfC.textWidth + 10,
                        'margin-right': scroll.config.width,
                        'margin-left': scroll.config.width
                })
                selfC.totalWidth = selfE.outerWidth(true);
                selfC.parentContainer.css({
                    width: scroll.config.width,
                    overflow: 'hidden',
                    margin: '0 auto'
                })
                scroll.animate(selfE);
            },
            animate: function (elem) {
                var self = this,
                    selfC = self.config,
                    selfE = selfC.container;
                selfE.animate({
                    'margin-left': '-=' + (selfC.totalWidth - selfC.width)
                }, selfC.speed, function () {
                    selfE.css({
                        'margin-left': scroll.config.width
                    })
                    selfE.scrollText(selfC); //.speed -= 1000
                });
            }
        };
        $.fn.scrollText = function (config) {
            return this.each(function () {
                var obj = Object.create(scroll);
                obj.init({
                    text: config.text,
                    speed: config.speed,
                    width: config.width,
                    container: $(this),
                    parent: config.parent || $(this).parent(),
                    parentContainer: config.parentContainer || $(this).parent().parent()
                }, this)
            });
        }
        $('#me, .scrollText').scrollText({
            text: 'Help us update the names on our site by going to "Account" and selecting one of the options',
            width: 250,
            speed: 15000
        });
        $('div').last().scrollText({
            text: 'another acroll',
            speed: 5000,
            width: 50
        })
    }())
})

我需要在不覆盖的情况下,将scrollText应用于尽可能多的自定义配置元素。

注意:当使用多个元素作为选择器调用.scrollText时,它的工作原理与上面的代码相同,但所有元素/实例的配置选项都是相同的

尝试将滚动对象重新定义为class

var Scroll = function () {
    this.config = {
        // initial config remain the same
    }
};
Scroll.prototype.init = function (config) {
    // init implementation remain the same
};
Scroll.prototype.animate = function (elem) {
    // animate implementation remain the same
};

现在,通过这个更改,您可以在scrollText函数上实例化一个新的Scroll实例,如下所示:

$.fn.scrollText = function (config) {
    return this.each(function () {
        var obj = new Scroll(); // here is the change
        obj.init({
            text: config.text,
            speed: config.speed,
            width: config.width,
            container: $(this),
            parent: config.parent || $(this).parent(),
            parentContainer: config.parentContainer || $(this).parent().parent()
        }, this)
    });
}

作为参数传递给object.create的对象被用作生成新对象的原型。如果参数的某个属性是对象或函数,则该属性将用作对原始属性的引用。

在此处阅读有关Object.create的更多信息

Object.create将无法工作,因为子对象(即嵌套对象)仍然是原始对象的子对象的引用,修复了一个不错的原型版本应该可以很好地工作。

该修复程序使用$.extend并传入一个名为config的新对象,而不是使用this.config,后者将覆盖以前的设置:

inif: function (config) {
    config = $.extend({}, this.config, config); //new object pulls defaults from this.config and overwrites it from params
    return this.setupHtml(config)//setup html
            .setupCss(config)//css 
            .animate(config, config.container)//animating. Note: always pass in that object so it don't use defaults;
}

小提琴来了:

http://jsfiddle.net/0eqxqvec/3/

附言:你也可以将原型配置重命名为默认值,然后在初始化时创建一个名为config的新属性,然后你可以使用this.config,fiddle:http://jsfiddle.net/0eqxqvec/4/

虽然我更喜欢使用params,但这只是我说我疯了,说我愚蠢。