【问题标题】:Is a Modal Confirm Box Using JQuery Possible?使用 JQuery 的模态确认框是否可行?
【发布时间】:2010-10-27 02:17:09
【问题描述】:

环顾四周,似乎找不到 JQuery 解决方案(也许它只是 JavaScript 的限制):

<a href="somelink.php" 
   onclick="return confirm('Go to somelink.php?');">Click Here</a>

在上面的例子中,当用户点击链接时,只有当用户在确认框中点击确定时,它才会转到它的href。

我想要做的是使用弹出 div 获得更现代的外观。也许是这样的:

<a href="somelink.php" 
   onclick="return jq_confirm('Go to somelink.php?');">Click Here</a>

(其中 jq_confirm 是一个自定义的 JQuery 确认函数,它会弹出一个带有 YES/NO 或 OK/CANCEL 按钮对的漂亮 div)。

但是,我似乎找不到任何这样的东西。

我查看了一些提供类似功能的 JQuery 小部件库等,但没有一个会等待用户的响应(至少,不是在上述场景中),而是它们只是继续并将用户带到链接(或运行嵌入在链接的 href='' 部分中的任何 JavaScript)。我怀疑这是因为虽然您可以将回调函数附加到其中许多小部件以返回真/假值,但 onclick 事件不会等待响应(回调是异步的 em>),从而破坏了确认框的目的。

我需要的是默认 confirm() 命令提供的相同类型的halt-all-javascript(模态)功能。这在 JQuery 中是否可行(甚至在 JavaScript 中)?

由于我不是 JavaScript 和 JQuery 方面的专家,所以我听从各位大师的意见。欢迎任何 JQuery(甚至纯 JavaScript)解决方案(如果可能)。

谢谢-

【问题讨论】:

  • 我有类似的问题..!将等待有人回答您的问题..!

标签: javascript jquery modal-dialog


【解决方案1】:

查看http://www.84bytes.com/2008/06/02/jquery-modal-dialog-boxes/

他们有各种各样的 JQuery 模式框。

我觉得你应该看看http://www.ericmmartin.com/simplemodal/

JavaScript 确认功能的模态对话框覆盖。演示 onShow 的使用以及如何显示模式对话框确认而不是默认的 JavaScript 确认对话框。

【讨论】:

  • 我评估了同样的代码,但它不适用于我描述的场景。问题是,我有数百个这样的 confirm() 代码通过我描述的编码的站点,并且宁愿只用 jq_confirm 做一个简单的替换 -> confirm() 而不是必须仔细重新编码数百页中的所有 href 和 onclick 代码(如果可能的话,那就是)。
【解决方案2】:

将重定向放在函数中,如:

<script>
    function confirmRedirect(url, desciption) {
       if (confirmWindow(desciption)) {
           window.location = url;
       }
    }
</script>

然后这样称呼它:

<a href="javascript:confirmRedirect('somlink.php','Are you sure?')">Go!</a> 

【讨论】:

  • 我建议不要使用 javascript:function() 内联代码,因为禁用 javascript 时它不会很好地降级。如果是这种情况,该链接将不会执行任何操作。而是使用 单击此处单击此处 就像在原始问题中所做的那样。
  • 问题是,我有数百个这样的 confirm() 代码通过我描述的编码的站点,并且宁愿只用 jq_confirm 做一个简单的替换 -> confirm() 而不是必须仔细重新编码所有 href以及数百个页面中的 onclick 代码(如果可能的话)。
  • 没有 javascript 的用户 = 谁在乎
【解决方案3】:

您应该能够重写标准的 window.confirm 函数来编写以下代码。

window.confirm = modalConfirm

那么你需要做一个这样的函数

function modalConfirm(message){
  // put your code here and bind "return true/false" to the click event
  // of the "Yes/No" buttons.
}

这应该可以,虽然我还没有测试过。我现在就要做这件事,并将让大家知道它是如何工作的。

编辑: 我现在已经测试了上面的示例,但这是不可能的,您必须像这样将回调函数传递给覆盖的确认函数:

function modalConfirm(message, callback){
  ... 
  $("button.yes").click(function(){
     callback(result);
  });
  ...
}

..使您对函数的调用如下所示:

confirm("Are you sure?", function(result){
  alert(result);
});

换句话说,不可能完全覆盖默认的 window.confirm 函数而不会导致导致浏览器挂起的令人讨厌的循环。我认为您将不得不像上面那样修改您的确认电话。

【讨论】:

    【解决方案4】:

    【讨论】:

    • 谢谢,我的谷歌上出现了很多不可靠的插件——这正是我需要的!
    • @Toskan - 我读到这个问题是因为 OP 希望能够设计和有效地自定义 confirm() 出现的对话框。由于样式是特定于浏览器的,因此 OP 将需要求助于对话框的客户端脚本实现,这是我推荐的。这怎么解决不了确认问题?
    • 亲爱的 RussCam:它显示了一个框,您可以在其中按下一些按钮 - 但这不是 OP 所要求的。他要求一个 javascript 停止事件执行,直到确认/取消。公认的解决方案(有 12 票赞成)是恕我直言。表演停止者恕我直言,您基本上会破坏所有点击事件并将其重定向到其他地方。其次想象 OP 决定在提交按钮上使用确认。拿一把大剑,斩断所有地方的所有事件,换一个确认框?干净的解决方案怎么样?
    【解决方案5】:

    我只需要解决同样的问题。我最终使用了来自JQuery UIdialog 小部件。我能够在不使用回调的情况下实现这一点,但需要注意的是 dialog 必须在 click 事件处理程序中为您想要使用确认功能的链接部分初始化(如果您想将其用于多个关联)。这是因为必须将链接的目标 URL 注入到确认按钮单击的事件处理程序中。

    这是我的解决方案,抽象出来以适合示例。我使用 CSS 类来指示哪些链接应该具有确认行为。

    <div id="dialog" title="Confirmation Required">
      Are you sure about this?
    </div>
    
    <script type="text/javascript">
      $(document).ready(function() {
        $("#dialog").dialog({
          autoOpen: false,
          modal: true
        });
    
      $(".confirmLink").click(function(e) {
        e.preventDefault();
        var targetUrl = $(this).attr("href");
    
        $("#dialog").dialog({
          buttons : {
            "Confirm" : function() {
              window.location.href = targetUrl;
            },
            "Cancel" : function() {
              $(this).dialog("close");
            }
          }
        });
    
        $("#dialog").dialog("open");
      });
    
    
    
    
      }); // end of $(document).ready
    
    
    </script>
    
    <a class="confirmLink" href="http://someLinkWhichRequiresConfirmation.com">Click here</a>
    <a class="confirmLink" href="http://anotherSensitiveLink">Or, you could click here</a>
    

    【讨论】:

    • 我想知道为什么这个解决方案被接受(和 12 个赞成票)。 OP 问题的答案是:没有这样的东西可以像确认一样停止所有 javascript 处理。出人意料地接受的解决方案(我猜)可能会随机执行一些 onclick 事件(如果有的话)。可能也取决于浏览器。整个确认对话框替换似乎没有干净的解决方案。
    • 完全同意托斯坎。此外,如果您仅依赖基于 js 的点击事件,那些禁用 js 的用户将不会被定向到任何地方。但是,我想这正是您要这样做的原因,不是吗?
    【解决方案6】:

    以下链接有一个用于确认框的 jQuery 插件,类似于在 JavaScript 中构造 like confirm("something")

    http://labs.abeautifulsite.net/archived/jquery-alerts/demo/

    【讨论】:

      【解决方案7】:

      我解决这个问题的方法是向对象添加一些任意数据,并在点击时检查该数据。如果存在,则正常使用该功能,否则使用是/否确认(在我的情况下使用 jqtools 覆盖)。如果用户单击是 - 在对象中插入数据,模拟另一次单击并擦除数据。如果他们单击“否”,则只需关闭叠加层。

      这是我的例子:

      $('button').click(function(){
          if ($(this).data('confirmed')) {
              // Do stuff
          } else {
              confirm($(this));
          }
      });
      

      这就是我为覆盖确认功能所做的(使用 jquery 工具覆盖):

      window.confirm = function(obj){
          $('#dialog').html('\
              <div>\
                  <h2>Confirm</h2>\
                  <p>Are you sure?</p>\
                  <p>\
                      <button name="confirm" value="yes" class="facebox-btn close">Yes</button>\
                      <button name="confirm" value="no" class="facebox-btn close">No</button>\
                  </p>\
              </div>').overlay().load();
          $('button[name=confirm]').click(function(){
              if ($(this).val() == 'yes') {
                  $('#dialog').overlay().close();
                  obj.data('confirmed', true).click().removeData('confirmed');
              } else {
                  $('#dialog').overlay().close();
              }
          });
      }
      

      【讨论】:

        【解决方案8】:

        以 Banu 的解决方案为基础(非常感谢!),使其成为每个页面顶部的一个流行解决方案。把这段代码粘贴进去:

        $(document).ready
        

        并将“confirmLinkFollow”类添加到您要确认的所有链接:

        $(".confirmLinkFollow").click(function(e) {
            e.preventDefault();
            var targetUrl = $(this).attr("href");
        var $dialog_link_follow_confirm = $('<div></div>').
                html("<p>Are you sure?</p>").
                dialog({autoOpen: false,
                title: 'Please Confirm',
                buttons : {
                    "Confirm" : function() { 
                        window.location.href = targetUrl; 
                },
                "Cancel" : function() { 
                        $(this).dialog("close"); 
                    }
                },
        
                modal: true,
            minWidth: 250,
            minHeight: 120
            }
            );
        
        
            $dialog_link_follow_confirm.dialog("open");
        });
        

        【讨论】:

          【解决方案9】:

          我在这里写了关于这个问题的解决方案的博客:http://markmintoff.com/2011/03/asp-net-jquery-confirm-dialog/

          尽管这篇文章是针对 ASP.Net 的,但它可以很容易地适应 php。它依赖于通过返回 false 来防止点击,并且当用户点击“确定”或“是”或你有什么时;只需再次单击链接或按钮。

          var confirmed = false;
          function confirmDialog(obj)
          {
              if(!confirmed)
              {
                  $( "#dialog-confirm" ).dialog({
                      resizable: false,
                      height:140,
                      modal: true,
                      buttons: {
                          "Yes": function()
                          {
                              $( this ).dialog( "close" );
                              confirmed = true; obj.click();
                          },
                          "No": function()
                          {
                              $( this ).dialog( "close" );
                          }
                      }
                  });
              }
          
              return confirmed;
          }
          

          试一试,让我知道你的想法。我希望这能解决您的问题。

          【讨论】:

          • 太棒了,这是我见过的唯一一个返回布尔值的答案(如最初要求的那样),将代码粘贴到 Mark 中?
          • 太棒了。它为我节省了一些丑陋的技巧。
          【解决方案10】:

          差不多三年后,我正在寻找类似的东西。由于我还没有找到一个可接受的“快速”解决方案,我写了一些非常接近 OP 标准的东西。我认为其他人将来可能会发现它很有用。

          JavaScript 是事件驱动的,这意味着它不支持我们可以用来暂停纯 JavaScript 确认函数的任何类型的“等待”或“睡眠”循环。这些选项包括消耗处理器周期、使用浏览器插件或 AJAX。在我们日益移动的世界中,有时互联网连接参差不齐,这些都不是很好的解决方案。这意味着我们必须立即从“确认”函数返回。

          但是,由于上面的代码sn-p中没有“假”逻辑(即用户点击“取消”时什么都不做),我们可以在点击“取消”时再次触发“点击”或“提交”事件用户单击“确定”。为什么不在我们的“确认”函数中设置一个标志并根据该标志做出反应?

          对于我的解决方案,我选择使用 FastConfirm 而不是“模态”对话框。您可以轻松地修改代码以使用您想要的任何内容,但我的示例旨在使用它:

          https://github.com/pjparra/Fast-Confirm

          由于这样做的性质,我看不到一个干净的方式来打包它。如果您觉得这有太多粗糙的边缘,请随意平滑它们或按照其他人推荐的方式重写您的代码:

          /* This version of $.fn.hasEvent is slightly modified to provide support for
           * the "onclick" or "onsubmit" tag attributes. I chose this because it was
           * short, even if it is cryptic.
           *
           * Learn more about the code by Sven Eisenschmidt, which is licensed under
           * the MIT and GPL at:
           *     http://github.com/fate/jquery-has-event
           */
          (function($) {
              $.fn.hasEvent = function(A, F, E) {
                  var L = 0;
                  var T = typeof A;
                  E = E ? E : this;
                  var V = (E.attr('on'+A) != undefined);
                  A = (T == 'string') ? $.trim(A) : A;
                  if (T == 'function')
                      F = A, A = null;
                  if (F == E)
                      delete(F);
                  var S = E.data('events');
                  for (e in S)
                      if (S.hasOwnProperty(e))
                          L++;
                  if (L < 1)
                      return V; // = false;
                  if (A && !F) {
                      return V = S.hasOwnProperty(A);
                  } else if(A && S.hasOwnProperty(A) && F) {
                      $.each(S[A], function(i, r) {
                          if(V == false && r.handler == F) V = true;
                      });
                      return V;
                  } else if(!A && F) {
                      $.each(S, function(i, s) {
                          if (V == false) {
                              $.each(s, function(k, r) {
                                  if (V == false && r.handler == F)
                                      V = true;
                              });
                          }
                      });
                  }
                  return V;
              }
              $.extend($, {hasEvent: $.fn.hasEvent});
          }) (jQuery);
          
          /* Nearly a drop-in replacement for JavaScript's confirm() dialog.
           * Syntax:
           *   onclick="return jq_confirm(this, 'Are you sure that you want this?', 'right');"
           *
           * NOTE: Do not implement "false" logic when using this function. Find another way.
           */
          var jq_confirm_bypass = false;
          function jq_confirm(el, question, pos) {
              var override = false;
              var elem = $(el);
          
              if ($.fn.fastConfirm == undefined) {
                  override = confirm(question);
              } else if (!jq_confirm_bypass) {
                  if (pos == undefined) {
                      pos = 'right';
                  }
          
                  elem.fastConfirm({
                      position: pos,
                      questionText: question,
                      onProceed: function(trigger) {
                          var elem = $(trigger);
                          elem.fastConfirm('close');
          
                          if (elem.hasEvent('click')) {
                              jq_confirm_bypass = true;
                              elem.click();
                              jq_confirm_bypass = false;
                          }
                          if (elem.hasEvent('submit')) {
                              jq_confirm_bypass = true;
                              elem.submit();
                              jq_confirm_bypass = false;
                          }
                          // TODO: ???
                      },
                      onCancel: function(trigger) {
                          $(trigger).fastConfirm('close');
                      }
                  });
              }
          
              return override ? override : jq_confirm_bypass;
          }
          

          所以... onclick="return confirm('你想测试这个吗?');"会变成 onclick="return jq_confirm(this, 'Do you want to test this?');" pos/"right" 参数是可选的,专门用于快速确认。

          当您单击时,jq_confirm() 函数将生成 jQuery 对话框并返回“false”。当用户点击“确定”时,jq_confirm() 设置一个标志,调用原始点击(或提交)事件,返回“true”,然后取消设置标志以防您想留在同一页面上。

          【讨论】:

            【解决方案11】:

            我有一个解决方案可以用来替换默认的 window.confirm 函数。它不需要您覆盖 window.confirm,因为这并不完全可能。

            我的解决方案允许您拥有像我这样的通用类,假设您将“确认操作”放在任何需要在处理之前进行确认的元素上。该脚本非常简单,使用 jQuery、jQuery UI Dialog 和其他插件。

            您可以在 jsFiddle http://jsfiddle.net/74NDD/39/ 上找到完整的实现演示。

            用法:

            • 在您的 html 头部或任何其他点击之前添加此 javascript 代码 您在 javascript 中的绑定。

              $("#dialog:ui-dialog").dialog("destroy");
              
              $('.confirm-action').live('click', function(e) {
                  $self = $(this);
              
                  if (e && e.stopImmediatePropagation && $self.data('confirmed') !== true) {
                      e.stopImmediatePropagation();
              
                      $('#confirm-action-dialog').dialog({
                          height: 110,
                          modal: true,
                          resizable: false,
                          draggable: false,
                          buttons: {
                              'Yes': function() {
                                  $(this).dialog('close');
                                  $self.data('confirmed', true);
                                  $self.click();
                              },
                              'No': function() {
                                  $self.data('confirmed', false);
                                  $(this).dialog('close');
                              }
                          }
                      });
                  } else if ($self.data('confirmed') === true) {
                      e = window.event;
                      e.cancelBubble = false;
                      $self.data('confirmed', false);
                  }
              
                  return false;
              });
              
            • 将此 html 放置在正文中的某个位置(默认情况下它是隐藏的)。

            • 将“确认操作”类放在任何需要确认的元素上。

              确认操作

            这个解决方案非常完美,因为它不会改变 jQuery 事件冒泡,它只是暂停(停止)所有其他事件,直到用户决定他们想要做什么。

            我希望这对其他人有帮助,因为我找不到任何其他不需要我安装另一个 jQuery 插件或进行其他黑客攻击的解决方案。

            【讨论】:

              【解决方案12】:

              由于这个问题似乎缺少规范答案:没有办法像alertconfirm 那样以编程方式暂停(和恢复)javascript 执行

              话虽如此,鉴于 javascript 的单线程性质,如今依赖这种行为通常被认为是不好的做法,而上述函数暂停执行的原因可能是因为它们是在 web 还处于早期阶段时设计的阶段,后来保持不变以确保兼容性。由于现在的重点是编写尽可能多的非阻塞 js 代码,因此以编程方式停止 js 的功能不太可能适用于任何未来的 ECMAScript 规范,因此您最好的选择是重新设计您的网站以确保确认和警报对话框可以与后台运行的其他 javascript 代码共存。

              【讨论】:

              • 确认不会暂停脚本,至少在我的系统上不会。
              猜你喜欢
              • 1970-01-01
              • 2011-07-15
              • 1970-01-01
              • 2014-01-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-05-03
              • 2011-10-17
              相关资源
              最近更新 更多