JavaScript锁定函数以防止递归(浏览器冻结/性能)

时间:2013-09-07 20:12:27

标签: javascript performance freeze

对于我的键盘电源键脚本,我已针对每个请求实施了一项功能,以启用up / down箭头键以关注复选框(向上和向下的行中的复选框表示电子邮件的桌子上的下方行上的复选框(显然就像旧雅虎经典邮件一样,虽然在他们停止允许访问之前我还没有意识到该功能)。此功能非常有用,只有一个例外:当我按住向上箭头键(而不是点击,点按)时,它会在Firefox到达顶部复选框时锁定;我越抓住它就越有可能KO浏览器,我将不得不手动终止该过程。

我对各种方法持开放态度,但涉及全局变量的任何内容必须使用option类。

框架明确禁止,我们正在谈论真实的代码和性能。

选项类,除非您的方法需要全局变量,否则没有必要......

var option = new function() {this.name = '';}

这是处理各种按键事件的功能......

function keyPressed(evt)
{
 var e = evt || event;
 var key = e.which || e.keyCode;

 if (powerKeysEnabled)
 {
  switch (key)
  {
   case 38://Up Arrow
   if (e.target.nodeName.toLowerCase()=='a' && e.target.previousSibling && e.target.previousSibling.nodeName.toLowerCase()=='input' && e.target.previousSibling.type=='checkbox' && e.target.parentNode.parentNode.nodeName.toLowerCase()=='tr')
   {
    var t;
    if (e.target.parentNode.parentNode.parentNode.parentNode.nodeName.toLowerCase()=='table') {t = e.target.parentNode.parentNode.parentNode.parentNode;}
    else if (e.target.parentNode.parentNode.parentNode.nodeName.toLowerCase()=='table') {t = e.target.parentNode.parentNode.parentNode;}

    var tr = t.getElementsByTagName('tr');

    for (var i=0; i<tr.length; i++)
    {
     if (tr[i]===e.target.parentNode.parentNode)
     {
      i--;

      if (tr[i])
      {
       var a = tr[i].getElementsByTagName('input');

       if (a[0] && a[0].type=='checkbox')
       {
        a[0].focus();
        break;
       }
       else
       {
        i--;

        if (tr[i])
        {
         var b = tr[i].getElementsByTagName('input');

         if (b[0] && b[0].type=='checkbox')
         {
          b[0].focus();
          break;
         }
        }
       }
      }
     }
    }
   }
   break;
  }
 }
}

任何对脚本如何工作感兴趣的人都应该意识到我将XHTML视为application/xhtml+xml,并且对于正确的代码非常清晰。还应该注意的是,我用锚点替换了不可自定义的输入复选框元素并隐藏了复选框(通过CSS position而不是 display),并在视觉上用锚元素替换每个复选框。请注意,空格在脚本解释XHTML的方式中非常重要,不要为了其他人而编辑。这是一个与......一起使用的示例XHTML表。

<table summary="This table displays emails from the currently choosen folder.">
<colgroup style="width: 5%;"></colgroup>
<colgroup style="width: 20%;"></colgroup>
<colgroup style="width: 50%;"></colgroup>
<colgroup style="width: 25%;"></colgroup>
<colgroup style="width: 5%;"></colgroup>
<thead><tr><td colspan="5"><span>Delete, move, other email features...</span></td></tr><tr><td><input type="checkbox" value="" /></td><td> </td><td> </td><td> </td><td> </td></tr></thead>
<tfoot><tr><td></td><td> </td><td> </td><td> </td><td> /td></tr></tfoot>
<tbody>
<tr id="mail_inbox_208_row"><td><input type="checkbox" value="" /></td><td> </td><td> </td><td> </td><td> </td></tr>
<tr id="mail_inbox_207_row"><td><input type="checkbox" value="" /></td><td> </td><td> </td><td> </td><td> </td></tr>
</tbody>
</table>

2 个答案:

答案 0 :(得分:0)

你是否尝试使用延迟为0的setTimeout'屈服'?如下所示:

function keyPressed(evt)
{
 var e = evt || event;
 var key = e.which || e.keyCode;

 if (powerKeysEnabled)
 {
    setTimeout(function() {
      //perform work here
    }, 0);
 }
}

答案 1 :(得分:0)

我为check-all复选框的id添加了一个排除项,它不再锁定;第二条如果条件......

if (
e.target.nodeName.toLowerCase()=='a' && 
e.target.id!='mail_inbox_all_img' && 
e.target.previousSibling && 
e.target.previousSibling.nodeName.toLowerCase()=='input' && 
e.target.previousSibling.type=='checkbox' && 
e.target.parentNode.parentNode.nodeName.toLowerCase()=='tr'
)