Javascript“无响应脚本”添加Jquery事件处理程序

时间:2010-12-01 07:19:23

标签: javascript jquery event-handling

我为Movember创建了一个小小的javascript网页,让用户“剃掉”胡须,或完全关闭。

我这样做是通过用一个div的网格覆盖一张剃光的图片来保持带有不同偏移的胡须图片。当用户将鼠标移动到其中一个div上时,它会消失,显示下面图片中的剃光皮肤。

问题在于,在创建4000个小div时,jquery.min.js脚本不断弹出“无响应脚本”错误。

我希望有人能在我的代码中找到效率非常低的东西,或者建议如何让Jquery吸一口气。我甚至尝试在代码运行时进行“加载...”旋转轮gif显示,但是javascript很快就扔掉了沙漏,以至于gif从未出现过。

以下是代码:

<script type="text/javascript">
var isErase = false;
var isCover = false;
var size = 4;
var i = 0;
var j = 0;
$(document).ready(function(){
 for (i = 0; i < 400; i += size) {
  for (j = 0; j < 250; j += size) {
   $('#picture').append('<div class="piece" style="background-position:  -' + j + 'px -' + i + 'px;" />');
  }
 }
 $('div.piece').click(function(event){
  isCover = false;
  isErase = ! isErase;
  if (isErase) $('#mode').html(' *** SHAVING ***');
  else $('#mode').html('OFF');
 });
 $('div.piece').dblclick(function(event){
  isErase = false;
  isCover = ! isCover;
  if (isCover) $('#mode').html(' *** UNSHAVING ***');
  else $('#mode').html('OFF');
 });
 $("div.piece").mouseenter(function(event){
  if (isErase) { $(this).addClass('invisible'); }
  else if (isCover) { $(this).removeClass('invisible'); }
 });
});
</script>

2 个答案:

答案 0 :(得分:4)

<script type="text/javascript">
var isErase = false;
var isCover = false;
var size = 4;
var i = 0;
var j = 0;
var str = '';
$(document).ready(function(){
 for (i = 0; i < 400; i += size) {
  for (j = 0; j < 250; j += size) {
    str += '<div class="piece" style="background-position:  -' + j + 'px -' + i + 'px;" />';
  }
 }

 $('#picture').html(str).delegate('div.piece', 'click', function (event) {
  isCover = false;
  isErase = ! isErase;
  if (isErase) $('#mode').html(' *** SHAVING ***');
  else $('#mode').html('OFF');
 }).delegate('div.piece', 'dblclick', function(event) {
  isErase = false;
  isCover = ! isCover;
  if (isCover) $('#mode').html(' *** UNSHAVING ***');
  else $('#mode').html('OFF');
 }).delegate('div.piece', 'mouseenter', function(event) {
  if (isErase) { $(this).addClass('invisible'); }
  else if (isCover) { $(this).removeClass('invisible'); }
 });
});
</script>

代码中最大的低效率如下:

  1. 操纵DOM 100,000次;每次都添加一个新的piece。使用HTML创建一个字符串并添加一次就会快得多。
  2. 不缓存您的jQuery选择器。你正在用“图片”的id查找div并构建一个1000次的jQuery对象。每次使用$('div.piece')时,您都会查找所有100,000个。链接你的jQuery方法,或者缓存对象。
  3. 将同一事件绑定到所有100,000 piece个。利用Javascripts事件冒泡,并将事件添加到元素的祖先(参见delegate())。

答案 1 :(得分:1)

这对我的safari有帮助,但无论哪种方式,我都不适合HTML和JavaScript。

<script type="text/javascript">
var isErase = false;
var isCover = false;
var size = 4;
var i = 0;
var j = 0;
$(document).ready(function(){
 for (i = 0; i < 400; i += size) {
  for (j = 0; j < 250; j += size) {
   $('#picture').append('<div class="piece" style="background-position:  -' + j + 'px -' + i + 'px;" />');
  }
 }
 $("#picture").live('click',function(event){
  isCover = false;
  isErase = ! isErase;
  if (isErase) $('#mode').html(' *** SHAVING ***');
  else $('#mode').html('OFF');
 });
 $("#picture").live('dblclick',function(event){
  isErase = false;
  isCover = ! isCover;
  if (isCover) $('#mode').html(' *** UNSHAVING ***');
  else $('#mode').html('OFF');
 });
 $("div.piece").live('mouseenter',function(event){
  if (isErase) { $(this).addClass('invisible'); }
  else if (isCover) { $(this).removeClass('invisible'); }
 });
});
</script>