简体   繁体   English

在JavaScript关闭方面遇到困难

[英]Having difficulties on JavaScript Closures

I wrote some JavaScript for a menu toggle, now I want to reuse this for multiple elements and im struggling on how I can create a closure to do this the right way. 我为菜单切换编写了一些JavaScript,现在我想将其重用于多个元素,并为如何创建一个正确的闭合方式而苦苦挣扎。

Now the effect is only on the last registered element, becaus of the scope of setup options etc. 现在,由于设置选项的范围等,效果仅在最后注册的元素上。

 var selectGroup = (function () { var defaults = { element: document.getElementById('form-select'), }; var setup = { open: false }; var opt = {}; self.init = function (options) { opt = options || defaults; opt.element = options.element || defaults.element; setup.navButton = opt.element.getElementsByClassName('nav-button')[0]; setup.ulTag = opt.element.getElementsByTagName('ul')[0]; setup.buttonArrow = opt.element.getElementsByTagName('span')[1]; registerEvents(); }; registerEvents = function () { opt.element.onclick = function () { if (setup.open) { setup.buttonArrow.setAttribute('class', 'expand-arrow'); setup.ulTag.setAttribute("style", 'max-height:0;'); } else { setup.buttonArrow.setAttribute('class', 'contract-arrow'); setup.ulTag.setAttribute("style", 'max-height:600px;'); } /*Toggle*/ setup.open = !setup.open; } }; return self; })(); selectGroup.init({element: document.getElementById('person-nav')}); selectGroup.init({element: document.getElementById('situation-nav')}); selectGroup.init({element: document.getElementById('region-nav')}); 

It is not a closure issue, you always overwrite your opt.element with the latest element, that's why only with the last one works. 这不是闭包问题,您总是用最新的元素覆盖opt.element ,这就是为什么只有最后一个起作用的原因。

You should save the datas in opts by a unique id. 您应该通过唯一ID将数据保存在opts中。

Here is a working example with super simple markup (ugly): https://jsfiddle.net/cone0oof/2/ 这是一个带有超级简单标记(丑陋)的工作示例: https : //jsfiddle.net/cone0oof/2/

The solution for this is to remove the closure, use the local scoped variables and pass them as parameters instead, because you want them to be created new for each different element. 解决方案是删除闭包,使用局部范围的变量并将其作为参数传递,因为您希望为每个不同的元素创建新的变量。

Below here is mostly the same as your original code. 下面的代码与您的原始代码基本相同。 I marked my changes with inline comments. 我用内嵌注释标记了更改。

var selectGroup = (function () {

    var defaults = {
        element: document.getElementById('form-select'),
    };

    self.init = function (options) {
        var setup = {   //make it local inside init()
            open: false
        };
        var opt = {};   //make it local inside init()

        opt = options || defaults;
        opt.element = options.element || defaults.element;
        setup.navButton = opt.element.getElementsByClassName('nav-button')[0];
        setup.ulTag = opt.element.getElementsByTagName('ul')[0];
        setup.buttonArrow = opt.element.getElementsByTagName('span')[1];
        registerEvents(opt, setup);  //pass them as parameters
    };


    registerEvents = function (opt, setup) { //receive the parameters
        opt.element.onclick = function () {
            if (setup.open) {
                setup.buttonArrow.setAttribute('class', 'expand-arrow');
                setup.ulTag.setAttribute("style", 'max-height:0;');
            } else {
                setup.buttonArrow.setAttribute('class', 'contract-arrow');
                setup.ulTag.setAttribute("style", 'max-height:600px;');
            }
            /*Toggle*/
            setup.open = !setup.open;
        }
    };

    return self;
})();

selectGroup.init({element: document.getElementById('person-nav')});
selectGroup.init({element: document.getElementById('situation-nav')});
selectGroup.init({element: document.getElementById('region-nav')});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM