use*_*284 37 javascript jquery asynchronous dialog synchronous
目前,我正在努力用jquery对话框替换"alert"/"confirm".
但是大多数遗留代码都是以某种异步方式编写的,这使得它很难改变.有没有办法让jquery对话框以同步方式工作?(不要使用循环或回调函数)
For example:
function run()
{
var result = confirm("yes or no");
alert( result );
\\more codes here
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,警报和其他代码将在用户选择后执行.
如果我们使用jquery对话框var result = $ dialog.open()它将继续执行异步警报.
目前,我的解决方案是在OK | Cancel功能中使用回调函数.例如:
OK: function ()
{
$dialog.close();
alert("yes");
//more codes here
}
Run Code Online (Sandbox Code Playgroud)
此方法有效,但很难使所有同步代码变为异步,这需要进行大量更改(请参阅以下示例).所以我正在寻找同步jQuery Dialog,它可能吗?
例如:(实际代码比下面的例子复杂得多)
function f1()
{
if ( confirm("hello") ) f2();
alert("no");
}
function f2()
{
if( confirm("world") ) f3();
alert("no");
}
function f3()
{
return confirm("!") ;
}
Run Code Online (Sandbox Code Playgroud)
另一个例子:
vendorObject.on('some-event', function() {
if(confirm("Do you really want to do that?")) {
return true;
}
else {
return false; // cancel the event
}
});
Run Code Online (Sandbox Code Playgroud)
...此处供应商对象触发一个事件,如果用户确认,该事件必须被取消.只有事件处理程序返回false- 同步时才能取消该事件.
gil*_*ly3 35
简短的回答是否定的,您将无法保持代码同步.原因如下:
要说明此行为,请调试代码并在更改UI的行后面的行上设置断点:
$("body").css("backgroundColor", "red");
var x = 1; // break on this line
Run Code Online (Sandbox Code Playgroud)
请注意,您的页面背景还不是红色.在您恢复执行并且脚本完成执行之前,它不会更改为红色.当您的调试器暂停执行脚本时,您也无法单击页面中的任何链接.
这个规则有一个例外,alert()和confirm().这些是浏览器控件,其处理方式与实际网页UI元素不同.
好消息是转换代码真的不是很难.据推测,您的代码目前看起来像这样:
if (confirm("continue?")) {
// several lines of code if yes
}
else {
// several lines of code if no
}
// several lines of code finally
Run Code Online (Sandbox Code Playgroud)
你的异步版本可以创建一个函数ifConfirm(text, yesFn, noFn, finallyFn),你的代码看起来非常相似:
ifConfirm("continue?", function () {
// several lines of code if yes
},
function () {
// several lines of code if no
},
function () {
// several lines of code finally
});
Run Code Online (Sandbox Code Playgroud)
编辑:回答您添加到问题中的其他示例,遗憾的是,该代码需要重构.根本不可能有同步自定义确认对话框.要在事件需要继续或取消的场景中使用自定义确认对话框,您只需要始终取消事件并模拟yesFn回调中的事件.
例如,一个链接:
$("a[href]").click(function (e) {
e.preventDefault();
var link = this.href;
ifConfirm("Are you sure you want to leave this awesome page?", function () {
location.href = link;
});
});
Run Code Online (Sandbox Code Playgroud)
或者,表格:
$("form").submit(function (e) {
e.preventDefault();
var form = this;
ifConfirm("Are you sure you're ready to submit this form?", function () {
form.submit();
});
});
Run Code Online (Sandbox Code Playgroud)
我不确定不使用回调的动机是什么,因此很难判断哪种解决方案可能满足您的要求,但延迟执行的另一种方法是通过jQuery的"延迟"对象.
http://api.jquery.com/category/deferred-object/
您可以设置一个打开jquery对话框的函数,并添加"等待"对话框关闭的代码.在您已经布局的情况下,这最终会以与回调相似的方式工作,但这是一个示例:
function confirm () {
var defer = $.Deferred();
$('<div>Do you want to continue?</div>').dialog({
autoOpen: true,
close: function () {
$(this).dialog('destroy');
},
position: ['left', 'top'],
title: 'Continue?',
buttons: {
"Yes": function() {
defer.resolve("yes"); //on Yes click, end deferred state successfully with yes value
$( this ).dialog( "close" );
},
"No": function() {
defer.resolve("no"); //on No click end deferred successfully with no value
$( this ).dialog( "close" );
}
}
});
return defer.promise(); //important to return the deferred promise
}
$(document).ready(function () {
$('#prod_btn').click(function () {
confirm().then(function (answer) {//then will run if Yes or No is clicked
alert('run all my code on ' + answer);
});
});
});
Run Code Online (Sandbox Code Playgroud)
这里是在jsFiddle工作:http: //jsfiddle.net/FJMuJ/
小智 3
不,你不能在 Javascript 中执行任何同步操作(事实上,警报违反了规则)。Javascript 的核心是“单线程、异步”。
不过,您可以做的是禁用基础页面(类似灯箱)的功能,因此在您不执行对话框操作(无论是“确定”还是“取消”)之前,页面不会触发任何事件。认为这不能帮助您使同步代码正常工作。你必须重写。
| 归档时间: |
|
| 查看次数: |
40656 次 |
| 最近记录: |