【问题标题】:How to show multiple dialog polyfill?如何显示多个对话框 polyfill?
【发布时间】:2018-03-10 22:17:52
【问题描述】:

我有脚本可以打开 polyfill 对话框:

window.modalDialog = function (url, arg, opt) {
        url = url || ''; //URL of a dialog
        arg = arg || null; //arguments to a dialog
        opt = opt || 'dialogWidth:300px;dialogHeight:200px'; //options: dialogTop;dialogLeft;dialogWidth;dialogHeight or CSS styles

        var caller = modalDialog.caller.toString();
        var dialog = document.body.appendChild(document.createElement('dialog'));
        var splitter = opt.split(",");
        dialog.setAttribute('style', splitter[0].replace(/dialog/gi, ''));
        dialog.innerHTML = '<a href="#" id="dialog-close">&times;</a><iframe id="dialog-body" src="' + url + '" style="border: 0; width: 100%; height: 100%;"></iframe>';
        document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
        document.getElementById('dialog-close').addEventListener('click', function (e) {
            e.preventDefault();
            dialog.close();
        });
        dialog = document.querySelector('dialog');
        dialogPolyfill.registerDialog(dialog);

        function addListeners() {
            document.querySelector('dialog').addEventListener('mousedown', mouseDown, false);
            window.addEventListener('mouseup', mouseUp, false);
        }

        function mouseUp()
        {
            window.removeEventListener('mousemove', divMove, true);
        }

        function mouseDown(e) {
            window.addEventListener('mousemove', divMove, true);
        }

        function divMove(e) {
            var div = document.querySelector('dialog');
            div.style.position = 'absolute';
            div.style.top = e.clientY + 'px';
            div.style.left = e.clientX + 'px';
        }

        addListeners();
        dialog.showModal();
        dialog.addEventListener('close', function () {
            var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
            document.body.removeChild(dialog);
            nextStmts[0] = nextStmts[0].replace(/(window\.)?modalDialog\(.*\)/g, JSON.stringify(returnValue));
            eval('{\n' + nextStmts.join('\n'));
        });
        throw 'Execution stopped until modalDialog is closed';
    };

当我调用这个脚本时,对话框主体被替换为新的 url 而不是创建新的对话框。如何创建多个对话框?

编辑

我最大的问题是我的对话框有相同的父(调用者),所以在对话框polyfill js库中,有脚本检查父文档中是否有对话框,如果有,则抛出警告Failed to execute showModal on dialog: The element is already open, and therefore cannot be opened modally.

编辑

我已经创建了 jsfiddle,但我不知道如何从 jsfiddle 调用外部源网站。 https://jsfiddle.net/godofrayer/gvLpLjkq/

【问题讨论】:

  • this 有帮助吗?
  • 我正在使用他的代码,但仍然无法创建多个对话框。
  • 哦,是的,您正在使用该代码的一部分
  • 1) 通过两次调用spawn 函数,我能够使用showModalDialog 打开2 个不同的模式; 2) 它们有点破损(不会关闭),但可以轻松修复; 3) 如果您使用自己的设置提供可运行的演示,该设置不同于 spawn 的东西(在 jsfiddle、plunker 或其他上),我相信我们将有很好的机会解决您的问题也是。
  • 问题是document.getElementById。这假设该 id 只有一个元素;如果有两个,它总是会获取第一个。您可以改用dialog.querySelector( "#id" ) 来解决这个问题(不过,我建议您使用类,因为重复的 ID 违反规范)。 Here's a recursive fiddle example.

标签: javascript dialog modal-dialog


【解决方案1】:

我稍微修改了您的示例,现在您可以打开多个对话框。 问题是getElementById。 id 在文档中必须是唯一的。所以我将对话框组织在一个数组中,现在 ID 元素在 id 的末尾包含数组的索引:id="dialog-close'+dlgIndex+'"

我的修改是here

在这里您可以看到主要变化:

var dlgs = [];
    window.showModalDialog = window.showModalDialog || function(url, arg, opt) {
        url = url || ''; //URL of a dialog
        arg = arg || null; //arguments to a dialog
        opt = opt || 'dialogWidth:300px;dialogHeight:200px'; //options: dialogTop;dialogLeft;dialogWidth;dialogHeight or CSS styles        
        var caller = showModalDialog.caller.toString();

        var dialog = document.body.appendChild(document.createElement('dialog'));
        // Adds the Dialog to an Array of Dialogs
        var dlgIndex = dlgs.length;
        dlgs[dlgIndex] = dialog;
        dialog.setAttribute('style', opt.replace(/dialog/gi, ''));
        dialog.innerHTML = '<a href="#" id="dialog-close'+dlgIndex+'" style="position: absolute; top: 0; right: 4px; font-size: 20px; color: #000; text-decoration: none; outline: none;">&times;</a><iframe id="dialog-body'+dlgIndex+'" src="' + url + '" style="border: 0; width: 100%; height: 100%;"></iframe>';
        document.getElementById('dialog-body'+dlgIndex).contentWindow.dialogArguments = arg;
        document.getElementById('dialog-close'+dlgIndex).addEventListener('click', function(e) {
            e.preventDefault();
            dialog.close();
        });
        dialog.showModal();
        //if using yield
        if(caller.indexOf('yield') >= 0) {
            return new Promise(function(resolve, reject) {
                dialog.addEventListener('close', function() {
                    var returnValue = document.getElementById('dialog-body'+dlgIndex).contentWindow.returnValue;
                    document.body.removeChild(dialog);
                    resolve(returnValue);
                });
            });
        }
        //if using eval
        var isNext = false;
        var nextStmts = caller.split('\n').filter(function(stmt) {
            if(isNext || stmt.indexOf('showModalDialog(') >= 0)
                return isNext = true;
            return false;
        });
        dialog.addEventListener('close', function() {
            var returnValue = document.getElementById('dialog-body'+dlgIndex).contentWindow.returnValue;
            document.body.removeChild(dialog);
            nextStmts[0] = nextStmts[0].replace(/(window\.)?showModalDialog\(.*\)/g, JSON.stringify(returnValue));
            eval('{\n' + nextStmts.join('\n'));
        });
        //throw 'Execution stopped until showModalDialog is closed';
    };
})();

var showDialog = function() {
    window.showModalDialog("https://heise.de/");
  console.log("ShowSecond!!!")
  window.showModalDialog("https://www.heise.de/newsticker/meldung/Einstweilige-Verfuegung-Vodafone-muss-Kinox-to-sperren-3966023.html");
};

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多