在CefSharp

时间:2016-04-12 02:05:47

标签: javascript c# .net chromium-embedded cefsharp

我使用CefSharp编写了一个程序来刮擦网页。当我开始这个项目时,我没有意识到该网站使用了现已不存在的showModalDialog函数。我真的很喜欢CefSharp,如果我可以提供帮助,我不想使用.Net WebBrowser。我使用此处的代码的精简版本实现了showModalDialog的替换作为扩展:

https://github.com/niutech/showModalDialog

我创建了以下showModalDialog.js并将其添加为资源:

(function () {
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'));
    dialog.setAttribute('style', opt.replace(/dialog/gi, ''));
    dialog.innerHTML = '<a href="#" id="dialog-close" style="position: absolute; top: 0; right: 4px; font-size: 20px; color: #000; text-decoration: none; outline: none;">&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.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').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').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';
};
})();

我在初创公司的CefSharp中注册了它,如下所示:

            CefSettings settings = new CefSettings();

            settings.RegisterExtension(new CefExtension("showModalDialog", Resources.showModalDialog));

            //Perform dependency check to make sure all relevant resources are in our output directory.
            Cef.Initialize(settings, shutdownOnProcessExit: true, performDependencyCheck: true);

因此,当从网页调用showModalDialog时,它会弹出对话框。问题是它似乎没有正确传递参数。我正在抓取的页面设置了showModalDialog,如下所示:

    function popupPanel() { 
        var args = new Array(document.getElementById("IDofElementToReceiveTheValue"));
        var url = '<url of the html for the popup>'
        var windowParam = 'resizable=yes;dialogWidth=975px;dialogHeight=750px;scrollbars=yes;status=no';
        showModalDialog(url,args, windowParam);
        return true;
    }

弹出窗口显示带有选择列的记录列表。单击选择列中的链接时,此函数将触发:

function selectItem(keyvalue) {
    window.dialogArguments[0].value = keyvalue;
    window.close();
}

因此,当调用showModalDialog时,它会创建一个包含一个元素的数组,该元素应该接收所选记录的值。它将此数组作为参数传递给showModalDialog。 showModalDialog将此数组传递给弹出窗口的dialogArguments。当你选择一个项目时,它会抛出一个错误,说“索引0处没有对象为null”,窗口永远不会关闭(我认为这是因为它由于异常而永远不会进入该步骤)。出于某种原因,当调用selectItem函数时,窗口的dialogArguments为null。该对象不是从调用showModalDialog的初始设置到弹出窗口中的selectItem函数。任何人都可以解释为什么会这样吗?对此的任何帮助将不胜感激。

谢谢, 吉姆

0 个答案:

没有答案