【问题标题】:How to share a variable between 2 different functions?如何在 2 个不同的函数之间共享一个变量?
【发布时间】:2019-07-11 05:41:09
【问题描述】:

我有 2 个函数,分别称为 click 用于 PC 和 swipe 用于移动语句。每次您激活这些功能时,变量myCount 都会增加。但是问题是myCount在我点击移动语句上的按钮时增加了一倍。

How do i pass variables between functions in javascript

根据上面的链接,我尝试使用类似这样的嵌套函数来传递变量:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style media="screen" ref="">
      * {
        margin: 0;
        padding: 0;
      }
      .page1 {
        position: relative;
        width: 100vw;
        height: 100vh;
        background-color: grey;
        display: flex;
        flex-flow: row;
        justify-content: center;
        align-items: center;
      }
      .buttons {
        display: flex;
        flex-flow: row;
        justify-content: center;
        align-items: center;
      }
      .prev {
        position: absolute;
        left: 0;
        margin: 0 40px;
      }
      .shrink {
        position: absolute;
        flex-grow: 1.5;
      }
      .next {
        position: absolute;
        right: 0;
        margin: 0 40px;
      }
    </style>
  </head>
  <body>
    <div class="page1">
      <div class="buttons">
        <div class="button prev">Prev</div>
        <div class="shrink"></div>
        <div class="button next">Next</div>
      </div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
      $(function stripeAnimeModule() {
        // Variables (for Click)
        var _ = $('#stripe > .container > .grid > .inline-grid'),
            screen = $('.page1'),
            buttons = $('.page1 > .buttons > .button'),
            myCount = 1,
            x,
            dist;
        // functions
        function isclicked() {
          buttons.on({click: clicked})
          function clicked(e) {
            myCount += 1;
            istouched(myCount);
          }
        }
        function istouched(p) {
          screen.bind({touchstart: touchStart, touchmove: touchMove, touchend: touchEnd})
          console.log(p);
          function touchStart(e) {
            return x = e.touches[0].clientX;
            console.log(p);
          }
          function touchMove(e) {
            var drag = e.touches[0].clientX;
            var dist = Math.sqrt(x + drag);
            e.preventDefault();
          }
          function touchEnd(e) {
            var dist = e.changedTouches[0].clientX - x;
            console.log('basic log: ' + dist, myCount);
          }
        }
        isclicked();
      })
    </script>
  </body>
</html>

但是如果你想启动istouched功能,这个必须先点击按钮。之后,myCount 再次增加一倍。

这就是我目前的情况:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style media="screen" ref="">
      * {
        margin: 0;
        padding: 0;
      }
      .page1 {
        position: relative;
        width: 100vw;
        height: 100vh;
        background-color: grey;
        display: flex;
        flex-flow: row;
        justify-content: center;
        align-items: center;
      }
      .buttons {
        display: flex;
        flex-flow: row;
        justify-content: center;
        align-items: center;
      }
      .prev {
        position: absolute;
        left: 0;
        margin: 0 40px;
      }
      .shrink {
        position: absolute;
        flex-grow: 1.5;
      }
      .next {
        position: absolute;
        right: 0;
        margin: 0 40px;
      }
    </style>
  </head>
  <body>
    <div class="page1">
      <div class="buttons">
        <div class="button prev">Prev</div>
        <div class="shrink"></div>
        <div class="button next">Next</div>
      </div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
      $(function stripeAnimeModule() {
        // Variables
        var screen = $('.page1'),
        buttons = $('.page1 > .buttons').find('button'),
        myCount = 1,
        x,
        dist;
        // functions
        $(function istouched() {
          screen.bind({click: clicked, touchstart: touchStart, touchmove: touchMove, touchend: touchEnd})
          function clicked(e) {
            if (buttons.data('clicked', true)) {
              myCount += 1;
              console.log(myCount);
            }
          }
          function touchStart(e) {
            return x = e.touches[0].clientX;
          }
          function touchMove(e) {
            var drag = e.touches[0].clientX;
            var dist = Math.sqrt(x + drag);
            e.preventDefault();
            console.log(x, drag);
          }
          function touchEnd(e) {
            var dist = e.changedTouches[0].clientX - x;
            myCount += 1;
            console.log('distance is: ' + dist, 'myCount is: '+ myCount);
          }
        })
      })
    </script>
  </body>
</html>

我的期望是在 2 个不同的函数之间获得一个增量值myCount,并将该值存储为下一个增量。因此,如果您单击函数 a 第三次,滑动函数 b 第二次,那么 myCount 将是 5,而不是 3 和 2。

有什么解决办法吗?

【问题讨论】:

    标签: javascript jquery click swipe slide


    【解决方案1】:

    您可以使用Event bus pattern 做到这一点,它允许您在多个不同的功能之间共享您的数据。

    HTML

    <h2>COUNT: <span data-count>0</span></h2>
    
    <button id="btn1">Push Me 1</button><br><br>
    
    <button id="btn2">Push Me 2</button>
    



    JS 事件总线模式

    var EventManager = {
        subscribe: function(event, fn) {
            $(this).bind(event, fn);
        },
        publish: function(event) {
            $(this).trigger(event);
        }
    };
    
    // Register your custom code which can publish and subscribe to events
    EventManager.subscribe("increaseClickSwipeValue", function() {
        $('span[data-count]').text(Counter.increaseValue());
        // do something other   
    });
    
    // counter object which hold value
    var Counter = {
      value: 0,
    
      increaseValue: function() {
        this.value = this.value+1;
        return this.value;
      }
    };
    
    // listeners anywhere
    $('#btn1').on('click', function() {
      EventManager.publish("increaseClickSwipeValue");
    });
    
    $('#btn2').on('click', function() {
      EventManager.publish("increaseClickSwipeValue");
    });
    

    JSFIDDLE

    More about event bus

    【讨论】:

      【解决方案2】:

      如果您的变量与所有函数在同一范围内声明,则不需要在函数之间传递它,因为它将始终在父范围内更新。只有当您的函数超出此范围时,您才需要一些替代方法来跟踪该值。见例子:

      (function() {
        var $screen = $(".page1"),
          $buttons = $(".button"),
          myCount = 1,
          x,
          dist;
      
        function update() {
          console.log("distance is: " + dist, "myCount is: " + myCount);
          $('.count').text(myCount);
        }
      
        function clicked(e) {
          myCount += 1;
          update();
        }
      
        function touchStart(e) {
          return (x = e.touches[0].clientX);
        }
      
        function touchMove(e) {
          var drag = e.touches[0].clientX;
          var dist = Math.sqrt(x + drag);
          e.preventDefault();
        }
      
        function touchEnd(e) {
          var dist = e.changedTouches[0].clientX - x;
          myCount += 1;
          update();
        }
      
        $buttons.on('click', clicked);
        $screen.on('touchstart', touchStart);
        $screen.on('touchmove', touchMove)
        $screen.on('touchend', touchEnd)
      })();
      * {
        margin: 0;
        padding: 0;
      }
      
      .page1 {
        position: relative;
        width: 100vw;
        height: 100vh;
        background-color: grey;
        display: flex;
        flex-flow: row;
        justify-content: center;
        align-items: center;
      }
      
      .buttons {
        display: flex;
        flex-flow: row;
        justify-content: center;
        align-items: center;
      }
      
      .prev {
        position: absolute;
        left: 0;
        margin: 0 40px;
      }
      
      .shrink {
        position: absolute;
        flex-grow: 1.5;
      }
      
      .next {
        position: absolute;
        right: 0;
        margin: 0 40px;
      }
      
      .count {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <div class="page1">
        <div class="buttons">
          <div class="button prev">Prev</div>
          <div class="shrink"></div>
          <div class="button next">Next</div>
        </div>
        <div class="count"></div>
      </div>

      【讨论】:

      • 谢谢你的回答,但是当我点击移动语句上的按钮时myCount仍然增加了两倍。
      • 您在开始触摸事件时是否点击了移动设备上的按钮元素?因为这会导致计数增加两倍,因为仍然会在移动设备上触发 click 事件以及 touchend 事件。
      • 你可以用 mousedown 替换 click 事件,这应该否定这个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-20
      • 2012-11-14
      • 1970-01-01
      • 2020-08-24
      相关资源
      最近更新 更多