我正在使用画布库来执行一些具有库中不同画布功能的绘图(我正在使用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)
满足。必须有一种更有效的方法来实现这一目标。此外,如果我的函数运行时间太长而且事件监听器触发,那么全局变量不会及时更改?它看起来就像是非常糟糕的代码结构,例如我将在下面有更多的canvas函数。
$('#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;
});
解决此问题的最佳方法是什么?
谢谢!
答案 0 :(得分:1)
您可以设置一个可以在脚本中访问的公共变量,以便停止重新实例化同一个变量。此外,您可以执行委派的单击事件。在这种方法中,您不必创建大量的单击事件,这将允许您避免在特定元素上添加事件侦听器。
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>
答案 1 :(得分:0)
我不知道你的代码到底是怎样的, 但是你可以在所有函数之前声明var outsite。 instand在每个事件中声明它。 或者你可以这样做:
{{1}}
答案 2 :(得分:0)
将所有isEraserActive关闭对象作为常用类名,然后只使用一次:
$(".eraserOff").click(function() {
isEraserActive = false;
});
或者,使用其他一些常用选择器(您必须向我们展示您的HTML以便我们知道推荐什么),它会自动包含所有需要的元素。您还可以使用委托事件处理使用单个父事件处理程序,该处理程序检查单击的对象类型以决定是否应更改橡皮擦。对于多个元素,常见的事件处理程序总是有很多选项。使用哪种方法很大程度上取决于您尚未披露的特定HTML。
此外,如果我的函数运行时间太长而且事件监听器触发 全局变量不会及时改变吗?
不,这不是问题。如果你的功能需要很长时间才能运行,那么其他任何东西都没有运行,所以事情仍然正常排序。
答案 3 :(得分:0)
Revealing Module Pattern是一个很好的做法,因为你的变量是命名空间的,所以它不会与可能添加或运行的其他JS冲突。
var yourAppName = (function() {
var pub = {};
pub.eraser = false;
//API
return pub;
}());
设置此变量或进行检查
yourAppName.eraser //false
yourAppName.eraser = true;
yourAppName.eraser // true
也可能会使用JavaScript Closure,但有点难以理解。
答案 4 :(得分:0)
您可以将一个处理函数绑定到多个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));
等。
或者最好将所有这些对象添加到一个公共类中,然后将事件处理程序绑定到该类。