javascript - 如何实现 jQuery 模式的对象实例队列,确保每次只有一个实例打开?

标签 javascript jquery jquery-callback

我的任务是构建一个模态提示,到目前为止,当它归结为 DOM 操作时,描述它的方法(例如“显示”、“隐藏”)很简单。

现在对我来说困难来了......假设我们有一个页面,其中有多个立即调用来在一个页面上构建和显示多个模式

//on page load:

$("browser-deprecated-modal").modal();
$("change-your-city-modal").modal();
$("promotion-modal").modal();

默认情况下,我的模态(以及我尝试过的其他库)一次构造所有这些模态,并以相反的顺序显示它们彼此重叠 - 即 $(promotion-modal) 位于顶部,而 $("browser-deprecated-modal") 将位于所有这些的下方。这不是我想要的,更不用说重叠了。

我需要每个模态仅在前一个模态(如果有)关闭时才显示。因此,首先我们应该看到“browser-deprecated-modal”(下面没有其他模态),关闭它后必须弹出第二个模态,依此类推。

我一直在尝试解决这个问题:

$.fn.modal = function(options) {

  return this.each(function() {              
    if (Modal.running) {
        Modal.toInstantiateLater.push({this,options});
    } else {
         var md = new Modal(this, options);
    }
});
}

destroy :function () {
   ....
  if (Modal.toInstantiateLater.length)
  new Modal (Modal.toInstantiateLater[0][0],Modal.toInstantiateLater[0][1]);
}

跟踪在数组中构造 Modal 的所有调用,并在“destroy”方法中检查该数组是否为空。 但我认为这似乎很尴尬而且有问题。 我需要一个强大而清晰的解决方案。我一直在考虑 $.Callbacks 或 $.Deferred, 有点设置回调队列

if (Modal.running) { //if one Modal is already running

   var cb = $.Callbacks();
   cb.add(function(){
      new Modal(this, options);
   });

} else { //the road is clear
  var md = new Modal(this, options);
} 

并在 destroy 方法中触发 cb 触发,但我对这个东西很陌生,卡住了并且无法进展,无论它是否正确,或者其他方法更合适。 此外,我读到回调会立即触发所有函数(如果队列中有多个额外的模态),这是不对的,因为我需要一一触发模态创建并一一清除回调队列。

请帮助我解决这个问题。

我的代码jsfiddle

最佳答案

我去掉了计数器变量,因为您可以使用toInstantiateLater来跟踪您所在的位置,并且只需进行一些更改。尝试一下...

JavaScript

function Modal(el, opts){        
    this.el = $(el);
    this.opts = opts;
    this.overlay = $("<div class='overlay' id='overlay"+Modal.counter+"'></div>");
    this.wrap = $("<div class='wrap' id='wrap"+Modal.counter+"'></div>");
    this.replace = $("<div class='replace' id='replace"+Modal.counter+"'></div>");
    this.close = $("<span class='close' id='close"+Modal.counter+"'></span>")

    if (Modal.running) {
        Modal.toInstantiateLater.push(this);
    }
    else {
        Modal.running = true;
        this.show();
    }
}

Modal.destroyAll = function() {
    Modal.prototype.destroyAll();
};

Modal.prototype = {

    show: function() {
        var s = this;
        s.wrap.append(s.close);
        s.el.before(s.replace).appendTo(s.wrap).show();
        $('body').append(s.overlay).append(s.wrap);
        s.bindEvents();
        Modal.currentModal = s;
    },


    bindEvents: function() {
        var s = this;

        s.close.on("click.modal",function(e){
            s.destroy.call(s,e);
        });
    },

    destroy: function(e) {
        var s = this;

        s.replace.replaceWith(s.el.hide());
        s.wrap.remove();
        s.overlay.remove();

        if (Modal.toInstantiateLater.length > 0) {
            Modal.toInstantiateLater.shift().show();
        }
        else {
            Modal.running = false;
        }
    },

    destroyAll: function(e) {
        Modal.toInstantiateLater = [];
        Modal.currentModal.destroy();
    }

}

Modal.running = false;
Modal.toInstantiateLater = [];
Modal.currentModal = {};

$.fn.modal = function(options) {

      return this.each(function() {              
        var md = new Modal(this, options);
    });
}

$("document").ready(function(){

    $("#browser-deprecated-modal").modal();
    $("#change-your-city-modal").modal();
    $("#promotion-modal").modal();

    $("#destroy-all").on("click", function() {
        Modal.destroyAll();
    });
});

jsfiddle 示例

http://jsfiddle.net/zz9ccbLn/4/

关于javascript - 如何实现 jQuery 模式的对象实例队列,确保每次只有一个实例打开?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26929021/

相关文章:

javascript - 在滚动条上淡入另一个标志

javascript - 如何使用 John Resig JavaScript 微模板引擎?

javascript - 如何定位支持 jQuery 移动功能的手机?

javascript - 这种情况下如何实现回调函数

javascript - NODE 中同时 GET 和 POST 请求

javascript - jQuery:在文本区域段落中查找单词并将其替换为单词

jquery - 尝试删除通过我的 Raiks 应用程序中的 Jquery 呈现的评论

javascript - 如何在导航中选择元素

jQuery-文件-上传完成回调

jquery - 如果 jQuery 函数在其完成回调中调用自身,这会对堆栈造成递归危险吗?