jQuery嵌套函数变量作用域

时间:2019-09-06 13:11:31

标签: javascript jquery

即使我相信我使用的是全局变量,我也无法获得嵌套变量值来填充按钮的click事件函数内的嵌套函数之外。

将值放入嵌套函数之外的控制台日志中,我做错了什么?

我正在使用ajax和php利用jquery弹出窗口创建一个购物车。我能够将商品添加到购物车以及添加名称和电子邮件输入字段。

当我进入控制台登录Chrome的字段的焦点事件时,它们会显示值,但是当尝试使用Checkout按钮时,即使在使用嵌套功能的情况下,我也无法在Checkout点击范围内传递数据全局变量。

-JS-

   var formname;
$(document).ready(function() {
...
    $(document).on('click', '#check_out_cart', function(){            

          $('#cart-popover').popover({
                html : true,
                container: 'body',
                content:function(){
                  return $('#popover_content_wrapper').html();
                }
          });      

           $(document).on('click', '#cart-popover', function(){    
                  $('input#namef').focus();                   
          });

            $('input#namef').on('focusout', function(){                  
                    formname= $('input#namef').val();                         
                    console.log(formname);
            });

            var scart_add = $("input[name='scart_add']").val();
            console.log("Scart value is "+scart_add);
            console.log("Name is "+formname);
            ...

    });
});

-HTML-

 <div class="container">
              <nav class="navbar navbar-default" role="navigation">
                <div class="container-fluid">
                  <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Menu</span>
                    <span class="glyphicon glyphicon-menu-hamburger"></span>
                    </button>                    
                  </div>

                  <div id="navbar-cart" class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                      <li>
                        <a id="cart-popover" class="btn" data-placement="bottom" title="Shopping Cart">
                          <span class="glyphicon glyphicon-shopping-cart-2x"></span>
                          <span class="badge"></span>
                          <span class="total_price">$ 0.00</span>
                        </a>
                      </li>
                    </ul>
                  </div>                  
                </div>
              </nav>    
<div id="popover_content_wrapper" style="display: none">
              <span id="cart_details"></span>
              <div>
                <form method="POST">
                  Name:&nbsp;<input type="text" id="namef" >&nbsp;&nbsp;
                  Email:&nbsp;<input type="text" id="emailf" >&nbsp;&nbsp;
                  <input type="hidden" name="scart_add" value="1" /><br><br>
</div>
<div align="right">                  
               <button type="button" class="btn btn-primary" id="check_out_cart">
                  <span class="glyphicon glyphicon-shopping-cart"></span> Check out
                  </button>
                  <button type="button" class="btn btn-default" id="clear_cart">
                  <span class="glyphicon glyphicon-trash"></span> Clear
                  </button>                
</div>
</form>            
</div>
</div>
<div id="display_item">
</div>
...
</div>

我希望input#namef文本中的值出现在console.log ... formname变量中,但它只显示为“”。

3 个答案:

答案 0 :(得分:1)

focusout的事件不会添加到input,直到您click按钮: 另外,我不知道这是否是您复制和粘贴HTML和Javascript的方式,但是当我把它放在小提琴中时,它会抛出错误。

按照Rory指出的那样,将其移到按钮单击处理程序之外:

var formname;
$(document).ready(function() {
        //Now focusout handler is added on DOM Ready instead of when you click the button
        $('input#namef').on('focusout', function(){                  
               formname= $('input#namef').val();                         
               console.log(formname);
         });

         $(document).on('click', '#check_out_cart', function(){            

            var scart_add = $("input[name='scart_add']").val();
            console.log("Scart value is "+scart_add);
            console.log("Name is "+formname);

         });
});

这是一个工作的小提琴:https://jsfiddle.net/hqgv7zsa/

答案 1 :(得分:0)

这是一种竞赛条件。

  • document.ready事件中,您正在设置点击事件处理程序
  • 在点击处理程序中,您正在设置focusout事件处理程序
  • 由于点击处理程序仍在执行, 立即,代码运行以显示Scart和Formname的值。
  

当时,formname仍然为空,因为当前函数   (点击事件处理程序)仍在执行,焦点事件,甚至   如果触发,将在执行该代码后触发。


您应该将focusout处理程序声明代码移到click处理程序代码之外,这将在document.ready()事件上设置两个处理程序。

以下是发生的事情和发生的时间的详细信息:

var formname; 
$(document).ready(function() {

这会在加载DOM(document.ready事件)时触发

    $(document).on('click', '#check_out_cart', function(){            

当用户单击ID为check_out_cart的某个元素时触发

        $('input#namef').on('focusout', function(){ 

仅当用户单击购物车时设置此事件处理程序,但尚未执行!

                formname= $('input#namef').val();                         
                console.log(formname);
        });

focusout设置了事件处理程序后,此代码将触发,但仍未执行。即使触发了focusout事件,它也只会在当前函数退出时执行。

        var scart_add = $("input[name='scart_add']").val();
        console.log("Scart value is "+scart_add);

正确地,您会看到formname在这一点上是空的。

        console.log("Name is "+formname);
        ...
    });
});

希望这可以解释您所看到的流程;

快速解决方法,如Ryan Wilson的回答,将焦点处理程序声明移到click。处理程序外部的document.ready处理程序的范围内。

答案 2 :(得分:0)

使用Unable to fetch values from an input element in Bootstrap's popover中的解决方案,我能够调整我的JS代码,以在popover JS添加的.popover-content类中使用.find来获取值。

    var formname; 
    var formemail;       
$(document).ready(function() {
          //shopping cart

          /*load functions*/
          load_product();
          load_cart_data();

          $('#cart-popover').popover({
                html : true,
                container: 'body',
                content:function(){                  
                  return $('#popover_content_wrapper').html();
                }
          });

          $(document).on('click', '#cart-popover', function(){    
                  $('input#namef').focus();                   
          });

          $(document).on('focusout', '#namef', function(){
                formname = $('.popover-content').find('#namef').val();                
          });

          $(document).on('focusout', '#emailf', function(){                
                formemail = $('.popover-content').find('#emailf').val();
          });

           $(document).on('click', '#check_out_cart', function(){
                  var scart_add = $("input[name='scart_add']").val();
                  var nameval = $("input#namef").val();
                  alert("Scart value is "+scart_add);
                  alert("Name is "+formname);            
                  alert("Email is "+formemail); 

          });
});
相关问题