如何在两个不同的函数之间共享一个变量?

How to share a variable between 2 different functions?

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

How do i pass variables between functions in javascript

根据上述 link,我尝试使用嵌套函数来传递变量,如下所示:

<!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,并为下一次增量存储该值。因此,如果您第 3 次单击函数 a,然后第 2 次滑动函数 b,那么 myCount 将是 5,而不是 3 和 2。

有什么解决办法吗?

您可以使用 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

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

(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>