变量超出范围?

时间:2010-01-09 12:13:45

标签: javascript jquery scope

我的代码:

<html>

<head>

<script type="text/JavaScript" src="jquery-1.3.2.min.js"></script>
<script type="text/JavaScript" src="jquery.center.js"></script>
<script type="text/JavaScript">
    $(document).ready(function(){
        $('a').click(function(){
            popup_AskYN("Want me to tell you what 1 + 1 is?",function(){
                //popup_Info("It's 2, silly!");
            },function(){
                //popup_Info("I didn't want to, anyway!");
            });
        });
    });

    function popup_AskYN(msg,yes_fn,no_fn){
        $('body').append("<div id='popup'><p>"+msg+"</p><a id='popup_yes' href='#'>Yes!</a><a href='#' id='popup_no'>No.</a></div>");
        var yes_button = $('#popup_yes:last');
        var no_button = $('#popup_no:last');
        var popup = $('#popup:last');
        popup.center();

        yes_button.click(yes_fn);
        no_button.click(no_fn);

        yes_button.click(function(){
            popup.fadeOut('fast').remove();
        });
        no_button.click(function(){
            popup.fadeOut('fast').remove();
        });
    }

    function popup_Info(msg,callback){
        $('body').append("<div id='popup'><p>"+msg+"</p><a id='popup_ok' href='#'>Ok.</a></div>");
        var ok_button = $('#popup_ok:last');
        var popup = $('#popup:last');
        popup.center();

        ok_button.click(callback);

        ok_button.click(function(){
            popup.fadeOut('fast',function(){ $(self).remove(); });
        });
    }


</script>

<style type="text/css">
#popup {
    position:absolute;
    border:1px solid black;
}
#popup a {
    margin:10px;
}
</style>

</head>

<body>
<a href="#">Launch the popup!</a>
</body>

现在这很好用..除了我有多个弹出窗口。我把它缩小到的地方是,当我创建一个新的弹出窗口时,它会改变yes_button,no_button,ok_button和popup的值。因此,当前一个弹出窗口尝试使用这些变量时,它们都指向新的弹出窗口而不是当前弹出窗口。由于所有弹出窗口都具有相同的ID,因此我没有任何“唯一”来识别每个弹出窗口。我想只是存储选择器就足够了但是没有用。我能在这做什么?

已编辑,添加了正确的ID,但仍无法正常工作......:

<html>

    <head>
    <title>Call backs</title>

    <script type="text/JavaScript" src="jquery-1.3.2.min.js"></script>
    <script type="text/JavaScript" src="jquery.center.js"></script>
    <script type="text/JavaScript">
        $(document).ready(function(){
            $('a').click(function(){
                popup_AskYN("Want me to tell you what 1 + 1 is?",function(){
                    //popup_Info("It's 2, silly!");
                },function(){
                    //popup_Info("I didn't want to, anyway!");
                });
            });
        });

        var popup_AskYNId = 0;
        var popup_InfoId = 0;
        function popup_AskYN(msg,yes_fn,no_fn){
            popup_AskYNId = popup_AskYNId + 1;
            $('body').append("<div class='popup' id='"+popup_AskYNId+"popup_AskYN'><div class='popup_inner'><p>"+msg+"</p></div><div class='popup_options'><a class='popup_yes' id='"+popup_AskYNId+"popup_yes_AskYN' href='#'>Yes!</a><a href='#' class='popup_no' id='"+popup_AskYNId+"popup_no_AskYN' >No.</a></div></div>");
            popup = $('#'+popup_AskYNId+'popup_AskYN');
            yes_button = $('#'+popup_AskYNId+'popup_yes_AskYN');
            no_button = $('#'+popup_AskYNId+'popup_no_AskYN');

            popup.center();

            yes_button.click(yes_fn);
            no_button.click(no_fn);

            yes_button.click(function(){
                popup.fadeOut('fast').remove();
            });
            no_button.click(function(){
                popup.fadeOut('fast').remove();
            });
        }

        function popup_Info(msg,callback){
            $('body').append("<div id='popup'><div id='popup_inner'><p>"+msg+"</p></div><div id='popup_options'><a id='popup_ok' href='#'>Ok.</a></div></div>");
            ok_button = $('#popup_ok:last');
            popup = $('#popup:last');
            popup.center();

            ok_button.click(callback);

            ok_button.click(function(){
                popup.fadeOut('fast',function(){ $(self).remove(); });
            });
        }


    </script>

    <style type="text/css">

    .popup {
        position:absolute;
        border:1px solid black;
        padding:3px;
    }
    .popup_inner {
        border:1px solid black;
        padding:10px;
    }
    .popup_options {
        margin:0 auto;
    }
    .popup_options a {

        border:1px solid black;

        margin-top:3px;
        margin-left:3px;
        height:15px;
        width:75px;
        float:right;

        text-align:center;
        font-family:tahoma;
        font-size:0.8em;
        text-decoration:none;
        line-height:14px;
    }

    </style>

    </head>

    <body>
    <a href="#">Launch the popup!</a>
    </body>

</html>

解决方案被发现,但我修改了一点,所以是的,没有接受的功能像旧版本..

    $(function() {
  $('a').click(function(e) {
    e.preventDefault();

    var num1 = Math.floor(Math.random()*11),
    num2 = Math.floor(Math.random()*11);

    popup_AskYN(
        "Want me to tell you what 1 + 1 is?",
        function(){
            $('body').append('its 2');
        },function(){
            $('body').append('Fine.');
        });;
  });

  $('.popup_yes').live('click', function(e) {
    e.preventDefault();

    $(this).closest('.popup').fadeOut('fast', function() {
      $(this).remove();
    });
  });
  $('.popup_no').live('click', function(e) {
    e.preventDefault();

    $(this).closest('.popup').fadeOut('fast', function() {
      $(this).remove();
    });
  });

});

function popup_AskYN(msg, yes, no){
  $('body').append("<div class='popup'><div class='popup_inner'><p>"+msg+"</p></div><div class='popup_options'><a class='popup_yes' href='#'>Yes!</a><a href='#' class='popup_no'>No.</a></div></div>");
  var yes_button = $('.popup_yes:last');
  var no_button = $('.popup_no:last');
  var popup = $('.popup:last');

  yes_button.click(yes);

  no_button.click(no);
}

3 个答案:

答案 0 :(得分:1)

我看到你继续使用id = popup和许多其他带有硬编码ID的东西将div附加到文档中。在HTML中,ID在整个文档中必须是唯一的,并且特定ID(例如“弹出”)必须仅出现一次。当两个元素共享相同的ID时,会发生什么情况是未定义的,浏览器可以返回浏览器开发人员的任何内容。

因此,您的查询$('#popup:last')并不符合您认为的含义。

在这种情况下,常规DOM方法比jQuery-ism工作得好得多:

// shortcut. I hate typing document...
function newElement (tag, spec) {
    var el = document.createElement(tag);
    for (var n in spec) {
        el[n] = spec[n];
    }
    return el;
} 

function popup_AskYN(msg,yes_fn,no_fn){
    // because we get the references directly we don't need to
    // assign ids and therefore avoid id collisions:

    var popup = $(newElement('div')).append($(newElement('p')).append(msg));
    var yes_button = $(newElement('a',{href:'#'})).append('Yes!');
    var no_button = $(newElement('a',{href:'#'})).append('No.');

    popup.append(yes_button).append(no_button);
    popup.center();

    yes_button.click(yes_fn);
    no_button.click(no_fn);

    yes_button.click(function(){
        popup.fadeOut('fast').remove();
    });
    no_button.click(function(){
        popup.fadeOut('fast').remove();
    });

    $('body').append(popup);
}

答案 1 :(得分:1)

如果我只是将所有ID更改为类,这对我来说很好。将弹出窗口完全置于屏幕中心并不适合拥有弹出窗口的多个实例,如果这就是你所追求的。我不得不注释掉居中/定位代码,看它是否有效。

我还建议当有人点击弹出窗口中的是或否链接时,答案会替换原始弹出窗口的内容,而不是创建新的弹出窗口。我看到你试图在问题出现之前淡出问题,但请注意,在你当前的实现中,在动画结束之前删除了原始弹出问题,因此删除问题和创建新弹出窗口没有任何好处窗口与答案,而不是只是替换内容。

如果你希望问题在答案出现之前淡出,一个选项是仅在动画完成后删除问题弹出窗口,你可以用fadeOut的第二个参数来做,这是一个动画时要执行的回调完成。但是,这并不适合有多个弹出问题实例。原因是因为您的方法是删除问题并将答案附加到正文,因此答案弹出窗口与问题弹出窗口取消关联。这也可以通过简单地用答案替换问题来解决。如果您仍想要相同的淡入淡出效果,可以淡出弹出窗口,然后更改其内容,然后淡入淡出。

以下是您的代码版本,可以按照我的建议进行操作和更改:

<html>
<head>
  <script type="text/JavaScript" src="http://code.jquery.com/jquery.js"></script>
  <script type="text/JavaScript">
    $(function() {
      $('a').click(function(e) {
        e.preventDefault();

        var num1 = Math.floor(Math.random()*11),
        num2 = Math.floor(Math.random()*11);

        popup_AskYN(
          "Want me to tell you what " + num1 + " + " + num2 + " is?",
          "It's " + (num1 + num2) + ", silly!",
          "I didn't want to, anyway!"
        );
      });

      $('.popup_ok').live('click', function(e) {
        e.preventDefault();

        $(this).closest('.popup').fadeOut('fast', function() {
          $(this).remove();
        });
      });
    });

    function popup_AskYN(msg, yes, no){
      $('body').append("<div class='popup'><p>"+msg+"</p><a class='popup_yes' href='#'>Yes!</a><a href='#' class='popup_no'>No.</a></div>");
      var yes_button = $('.popup_yes:last');
      var no_button = $('.popup_no:last');
      var popup = $('.popup:last');

      yes_button.click(function() {
        popup.html('<p>' + yes + '<a class="popup_ok" href="#">Ok.</a>');
      });

      no_button.click(function() {
        popup.html('<p>' + no + '<a class="popup_ok" href="#">Ok.</a>');
      });
    }
  </script>

  <style type="text/css">
  .popup {
    border:1px solid black;
    margin-bottom: 10px;
  }
  .popup a {
    margin:10px;
  }
  </style>
</head>

<body>
  <a href="#">Launch the popup!</a>
</body>

答案 2 :(得分:0)

您可以使用现有弹出窗口的数量创建唯一标识符。

var popupId =  $("#popup").size();

然后使用id创建新的弹出窗口,并为按钮引用它。

$('body').append("<div id='" + popupId + "'><p>"+msg+"</p><a id='popup_ok' href='#'>Ok.</a></div>");