编写jQuery函数的好方法是为特定事件设置全局变量

A good way to write a jQuery function that sets a global variable for specific events?

本文关键字:事件 设置 全局变量 函数 jQuery 方法 编写      更新时间:2023-09-26

我正在使用一个画布库来执行一些具有库中不同画布功能的绘图(我使用的是fabric.js)

我的javascript技能一点也不好,所以我很感激关于如何正确构建代码的建议。请注意,这不是fabric.js的问题,只是javascript/jQuery。

我有一些画布函数,但当我需要删除对象/橡皮擦工具时,问题就出现了。

    var isEraserActive = false;
    $('#cursorCv').click(function(){
      canvas.isDrawingMode = false;
      isEraserActive = false;
    });
    $('#eraserCv').click(function(){
      canvas.isDrawingMode = false;
      canvas.deactivateAll().renderAll();
      isEraserActive = true;
    });
    canvas.on('object:selected', function(options){
  		if(isEraserActive){
        canvas.remove(options.target);
      }
    });
    
    

我不喜欢将isEraserActive = false;添加到每个函数中,只是为了使事件侦听器条件中的if(isEraserActive)满足。必须有一种更有效的方法来实现这一点。此外,如果我的函数运行时间过长,并且事件侦听器启动,全局变量不会及时更改吗?它看起来只是非常糟糕的代码结构,例如,我将在下面有更多的画布函数。

$('#squareCv').click(function(){
   var isEraserActive = false;   
});
$('#hollowSquareCv').click(function(){
   var isEraserActive = false;   
});
$('#circleCv').click(function(){
  var isEraserActive = false;    
});
$('#hollowCircleCv').click(function(){
   var isEraserActive = false;   
});
$('#fontTextCv').click(function(){
   var isEraserActive = false;   
});

处理这个问题的最佳方式是什么?

谢谢!

您可以设置一个公共变量,您可以在脚本中访问该变量,以便在重新实例化同一变量时停止。此外,您还可以执行委派的单击事件。在这种方法中,您不必创建大量的点击事件,这将避免在特定元素上添加事件侦听器。

var isEraserActive = true,
  eraserInActiveList = ['squareCv', 'hollowSquareCv', 'circleCv', 'hollowCircleCv', 'fontTextCv'];
$('#page-content').on('click', function(e) {
  var targetElement = e.target;
  
  if (targetElement && eraserInActiveList.indexOf(targetElement.id) > -1) {
    //For making eraser in active
    isEraserActive = false;
    alert('Eraser active: ' + isEraserActive);
  } else if (targetElement && targetElement.id === 'another-button') {
    //Do something else
    alert('Doing something else');
  } else if (false) {
      //Update with your own condition to meet your needs.
  }
  
});
#canvas-test {
  margin: 16px 12px;
  width: 100%;
  height: 250px;
  border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="page-content">
  <button type="button" id="squareCv">Square</button>
  <button type="button" id="hollowSquareCv">Hollow Square</button>
  <button type="button" id="circleCv">Circle</button>
  <button type="button" id="hollowCircleCv">Hollow Circle</button>
  <button type="button" id="fontTextCv">Font Text</button>
  <!-- Example content -->
  <canvas id="canvas-test"></canvas>
  <button type="button" id="another-button">Sample Button that do something else</button>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras maximus lacinia ligula, vitae ultrices sem ornare quis. Proin mi arcu, accumsan venenatis ligula eu, molestie laoreet turpis. Proin viverra feugiat dui, sit amet commodo sapien tincidunt
    in. Duis lacus tellus, pulvinar non tellus eget, faucibus aliquam libero. Duis condimentum quam tortor, suscipit molestie magna gravida et. Curabitur vel quam suscipit, condimentum felis ac, scelerisque mauris. Fusce id elit felis. Vestibulum id porta
    eros, efficitur tempus urna. Maecenas pulvinar arcu ut urna scelerisque rhoncus. Donec et ullamcorper dui. Donec non interdum elit. Quisque quis lectus facilisis, ultrices felis ac, rhoncus massa. Sed dictum tempor mi nec consequat. Phasellus pharetra
    ut mi eget pulvinar. Nulla tempor nunc at dolor vestibulum consequat.</p>
  <hr />
  <p>Suspendisse quis felis feugiat, aliquam nulla at, lobortis mi. Nulla mattis vitae ante sed vehicula. Quisque dui justo, ultricies quis iaculis suscipit, scelerisque at erat. Proin rhoncus at mauris eget suscipit. Aliquam interdum sollicitudin posuere.
    Pellentesque hendrerit placerat venenatis. Etiam quis euismod ex, at elementum diam.</p>
</section>

我不知道你的代码到底是什么样子的,但是您可以在所有函数之前声明var outsite。instand of在每个事件中声明它。或者你可以这样做:

$('#hollowCircleCv,#fontTextCv,#circleCv,#hollowSquareCv,#squareCv').click(function(){
   var isEraserActive = false;   
});

给所有isEraserActive关闭对象一个通用类名,然后只使用一次:

$(".eraserOff").click(function() {
    isEraserActive = false;
});

或者,使用其他一些常见的选择器(您必须向我们展示您的HTML,以便我们知道该推荐什么),它会自动包含所有所需的元素。您还可以使用使用委托事件处理的单亲事件处理程序,该事件处理程序检查单击的对象类型,以决定是否应该更改橡皮擦。对于多个元素的通用事件处理程序,总是有很多选项。使用哪一种在很大程度上取决于您尚未披露的特定HTML。

此外,如果我的函数运行时间过长,并且事件侦听器启动全局变量不会随时间变化吗?

不,这不是问题。如果你的函数需要很长时间才能运行,那么其他函数也不会运行,所以事情仍然可以正常排序。

揭示模块模式是一种很好的做法,因为您的变量是按名称命名的,所以它不会与可能添加或运行的其他JS冲突。

var yourAppName = (function() {
    var pub = {};
    pub.eraser = false;
    //API
    return pub;
}());

设置此变量或检查

yourAppName.eraser //false
yourAppName.eraser = true;
yourAppName.eraser // true

JavaScript闭包也可以使用,但有点难以理解。

您可以将一个处理程序函数绑定到多个HTML DOM事件。例如:

function setEraserClickHandler(event){
    isEraserActive = false;
}
$('#squareCv').click(setEraserClickHandler);
$('#hollowSquareCv').click(setEraserClickHandler);
$('#circleCv').click(setEraserClickHandler);
$('#hollowCircleCv').click(setEraserClickHandler);
$('#fontTextCv').click(setEraserClickHandler);

或者您也可以将参数发送到处理程序:

function setEraserClickHandler(eraser_active, event){
    isEraserActive = eraser_active;
}
$('#fontTextCv').click(this.setEraserClickHandler.bind(this, false));
$('#hollowSquareCv').click(this.setEraserClickHandler.bind(this, false));

等等。。

或者,最好向所有这些对象添加一个公共类,然后将事件处理程序仅绑定到该类。