Javascript 如何提高这个js脚本的性能(函数调用呈指数级增长)?
如何增加这样的长js代码?它工作得很好,但有时会有点慢,所有的拖放和ajax特性都会变慢 我知道这段代码有点长,所以我不寻求具体的建议。快速浏览一下这段代码后的第一个想法 编辑: 我发现了一件非常可怕的事情。对dragDrop()的调用在$('.folderListOnclick')中呈指数级增长。单击事件。每次单击后,会调用dragDrop()1次、2次、4次、8次。这就是让它慢下来的原因 但我不明白为什么会这样Javascript 如何提高这个js脚本的性能(函数调用呈指数级增长)?,javascript,jquery,Javascript,Jquery,如何增加这样的长js代码?它工作得很好,但有时会有点慢,所有的拖放和ajax特性都会变慢 我知道这段代码有点长,所以我不寻求具体的建议。快速浏览一下这段代码后的第一个想法 编辑: 我发现了一件非常可怕的事情。对dragDrop()的调用在$('.folderListOnclick')中呈指数级增长。单击事件。每次单击后,会调用dragDrop()1次、2次、4次、8次。这就是让它慢下来的原因 但我不明白为什么会这样 <script type="text/javascript">
<script type="text/javascript">
//<!--
$(document).ready(function() {
function in_array (needle, haystack, argStrict) {
var key = '', strict = !!argStrict;
if (strict) {
for (key in haystack) {
if (haystack[key] === needle) {
return true; }
}
} else {
for (key in haystack) {
if (haystack[key] == needle) {
return true;
}
}
}
return false;
}
var openedFolders = new Array();
var start = 0;
var stop = 0;
$('.drag').each(function() {
var draggables = $(this).parents('table').find('.drag');
var $next = draggables.filter(':gt(' + draggables.index(this) + ')').first();
var width = $(this).css('width');
var nextWidth = $next.css('width');
if (nextWidth > width /*&& 30 == parseInt(width)*/) {
$(this).removeClass('ordinaryFolderClosed');
$(this).removeClass('ordinaryFolderOpened');
if (in_array($(this).attr('rel'), openedFolders)) {
$(this).addClass('ordinaryFolderOpened');
} else {
$(this).addClass('ordinaryFolderClosed');
}
}
if (in_array($(this).attr('rel'), openedFolders)) {
start = 1;
}
if (1 == start && stop < 2) {
if (30 == parseInt(width)) {
stop++;
}
} else {
start = 0;
stop = 0;
if (parseInt(width) > 30) {
$(this).parent().parent().hide();
}
}
});
function dragDrop()
{
$('.folders .trow1').hover(
function () {
if ($(this).css('backgroundColor') != 'rgb(52, 108, 182)' && $(this).css('backgroundColor') != '#346cb6') {
$(this).css('background', "#C2E3EF");
}
},
function () {
if ($(this).css('backgroundColor') != 'rgb(52, 108, 182)' && $(this).css('backgroundColor') != '#346cb6') {
$(this).css('background', 'transparent');
}
}
);
$('.drag').click(function() {
if ($(this).hasClass('noclick')) {
$(this).removeClass('noclick');
} else {
var draggables = $(this).parents('table').find('.drag');
var $next = draggables.filter(':gt(' + draggables.index(this) + ')').first();
var width = $(this).css('width');
var nextWidth = $next.css('width');
if (nextWidth > width /*&& 30 == parseInt(width)*/) {
var isVisible = $next.is(':visible');
if (isVisible) {
$(this).removeClass('ordinaryFolderClosed');
$(this).removeClass('ordinaryFolderOpened');
$(this).addClass('ordinaryFolderClosed');
} else {
$(this).removeClass('ordinaryFolderClosed');
$(this).removeClass('ordinaryFolderOpened');
$(this).addClass('ordinaryFolderOpened');
}
clickedId = $(this).attr('rel');
clickedId = clickedId.split(',');
clickedType = clickedId[1];
clickedId = clickedId[0];
// $.ajax({
// type: 'POST',
// url: 'body/obsah/mediaManager/setOpenedFolder.php',
// data: 'id='+clickedId+'&type='+clickedType,
// success: function(msg){
// //alert(msg);
// }
// });
var start = 0;
var stop = 0;
var i = 0;
// close folder
if (isVisible) {
$('.drag').each(function() {
if (0 == start) {
iteratedId = $(this).attr('rel');
iteratedId = iteratedId.split(',');
iteratedId = iteratedId[0];
if (iteratedId == clickedId) {
start = 1;
}
}
if (1 == start && stop < 2) {
if ($(this).css('width') > width) {
$(this).parent().parent().hide();
if ($(this).hasClass('ordinaryFolderClosed') || $(this).hasClass('ordinaryFolderOpened')) {
$(this).removeClass('ordinaryFolderClosed');
$(this).removeClass('ordinaryFolderOpened');
$(this).addClass('ordinaryFolderClosed');
}
} else {
stop++;
}
}
i++;
});
}
// open folder
else {
$('.drag').each(function() {
if (0 == start) {
iteratedId = $(this).attr('rel');
iteratedId = iteratedId.split(',');
iteratedId = iteratedId[0];
if (iteratedId == clickedId) {
start = 1;
}
}
if (1 == start && stop < 2) {
if (parseInt($(this).css('width')) == parseInt(width)+5) {
$(this).parent().parent().show();
}
if (parseInt($(this).css('width')) == parseInt(width)) {
stop++;
}
}
i++;
});
}
}
}
});
var dragId = 0;
var dragType = 0;
var dropId = 0;
var dropType = 0;
var isFile = false;
$('.drag').draggable({
revert: true,
cursorAt: {top: 0, left: 0},
drag: function() {
if ($(this).attr('rel') !== undefined) {
dragId = $(this).attr('rel');
dragId = dragId.split(',');
dragType = dragId[1];
dragId = dragId[0];
}
isFile = false;
},
start: function(event, ui) {
$(this).addClass('noclick');
}
});
$('.drag2').draggable({
revert: true,
cursorAt: {top: 0, left: 0},
drag: function() {
if ($(this).attr('rel') !== undefined) {
dragId = $(this).attr('rel');
dragId = dragId.split(',');
dragType = dragId[1];
dragId = dragId[0];
}
isFile = true;
}
});
$('.drop').droppable({
tolerance: 'pointer',
drop: function() {
if ($(this).attr('rel') !== undefined) {
dropId = $(this).attr('rel');
dropId = dropId.split(',');
dropType = dropId[1];
dropId = dropId[0];
if (dropId != dragId) {
if (false == isFile) {
$.ajax({
type: 'POST',
url: 'body/obsah/mediaManager/folder_move.php',
data: 'nid='+dragId+'&pid='+dropId+'&ft='+dropType,
success: function(msg){
ajaxElementCall('left1', 'body/obsah/mediaManager/folder_list.php?type=1', 'right1', 'body/obsah/mediaManager/file_list.php?type=1&browse=0&assignType=0&CKEditorFuncNum=0&idFolder=0');
dragDrop();
}
});
} else if (true == isFile) {
$.ajax({
type: 'POST',
url: 'body/obsah/mediaManager/file_move.php',
data: 'fid='+dragId+'&did='+dropId+'&ft='+dropType,
success: function(msg){
ajaxElementCall('right1', 'body/obsah/mediaManager/file_list.php?type=1&browse=0&assignType=0&CKEditorFuncNum=0&idFolder=0&reloadTree=0');
dragDrop();
}
});
}
}
}
}
});
}
dragDrop();
$('.folderListOnclick').click(function() {
var append = 'idFolder='+$(this).attr('rel')+'&browse=0&assignType=0&CKEditorFuncNum=0&reloadTree=0';
ajaxElementCall('right1', 'body/obsah/mediaManager/file_list.php?type=1&'+append);
dragDrop();
$('.trow1').css('background', 'transparent');
$('.trow1').css('color', '#3e4245');
$(this).parent().css('background', "#346cb6 url('img/menuButtonOver.png') left top repeat-x");
$(this).parent().css('color', 'white');
});
$('.folderEditOnclick').click(function() {
var append = 'idFolder='+$(this).attr('rel')+'&browse=0&assignType=0&CKEditorFuncNum=0';
showModal('modal_div', 'Editácia adresára');
ajaxElementCall('modal_div', 'body/obsah/mediaManager/folder_edit.php?kam=edit1&'+append);
});
$('.folderDeleteOnclick').click(function() {
var append = 'idFolder='+$(this).attr('rel')+'&browse=0&assignType=0&CKEditorFuncNum=0';
showModal('modal_div', 'Vymazanie adresára');
ajaxElementCall('modal_div', 'body/obsah/mediaManager/folder_delete.php?kam=del1&'+append);
});
$('.addNewFolder').click(function() {
showModal('modal_div', 'Nový adresár');
var id = '0';
$('.folders .trow1').each(function() {
if ($(this).css('backgroundColor') == 'rgb(52, 108, 182)' || $(this).css('backgroundColor') == '#346cb6') {
id = $(this).attr('rel');
id = id.split(',');
id = id[0];
}
});
ajaxElementCall('modal_div', '/body/obsah/mediaManager/folder_add.php?type=1&kam=new1&idFolder='+id+'&browse=0&assignType=0&CKEditorFuncNum=0');
});
}); //-->
</script>
//
像$(this)
这样的查找操作非常昂贵。您最好存储和寻址对象引用;在类似的情况下,它对我帮助很大。像$(this)
这样的查找操作非常昂贵。您最好存储和寻址对象引用;在类似的情况下,它对我帮助很大。首先,所有的$(this)
都应该更改为使用变量
var me = $(this);
me.XXX
$(this)
是一个方法调用,不需要在同一个对象上反复调用它
这需要在每个块的基础上进行,因为每个块中的对象不同;) 首先,所有的$(this)
都应该更改为使用变量
var me = $(this);
me.XXX
$(this)
是一个方法调用,不需要在同一个对象上反复调用它
这需要在每个块的基础上进行,因为每个块中的对象不同;) 它不会使速度加快很多,但会使速度加快几毫秒:
您应该重用jquery实例,而不是生成新实例(这需要一些时间)
例:代替
$(this).parent().css('background', "#346cb6 url('img/menuButtonOver.png') left top repeat-x");
$(this).parent().css('color', 'white');
使用
它不会使速度加快很多,但这会使速度加快几毫秒:
您应该重用jquery实例,而不是生成新实例(这需要一些时间)
例:代替
$(this).parent().css('background', "#346cb6 url('img/menuButtonOver.png') left top repeat-x");
$(this).parent().css('color', 'white');
使用
可以显著优化上述代码的一件事是将in_数组函数和openedFolders数组替换为一个JS对象,该对象起到字典的作用,效率更高。
减容:
openedFolders={};
将新文件夹添加到打开的文件夹对象:
openedFolders[folderName]=valueRelatedToTheFolderIfYouHaveOneOrWhatEver; // :)
搜索打开的文件夹:
if(openedFolders.hasOwnProperty(folderName)){/*folderName is open*/}
可以显著优化上述代码的一件事是将in_数组函数和openedFolders数组替换为一个JS对象,该对象起到字典的作用,效率更高。
减容:
openedFolders={};
将新文件夹添加到打开的文件夹对象:
openedFolders[folderName]=valueRelatedToTheFolderIfYouHaveOneOrWhatEver; // :)
搜索打开的文件夹:
if(openedFolders.hasOwnProperty(folderName)){/*folderName is open*/}
您还没有发布任何HTML标记,也没有发布“ajaxElementCall”函数功能的详细信息。因此,很难说你应该如何解决这个问题。但是,在每次“drop”事件中,您都会再次调用“dragDrop()”设置函数。您说“ajaxElementCall”重新加载页面的某些部分,但您的“dragDrop()”代码总是在页面上的所有元素上安装新的事件处理程序。如果“ajaxElementCall”只更新了页面的一部分,那么所有未更改的“.drag”和“.drop”元素都会堆积额外的事件处理程序
当您为某些选择器调用.click()
或.hover()
时,jQuery会将您提供的事件处理程序添加到已注册的处理程序集中。因此,因为每次调用“dragDrop()”时都要注册新的事件处理程序,所以会越来越多地堆积起来。当事件发生时,所有这些处理程序都将运行
可能您需要做的是更改“dragDrop()”,这样您就可以告诉它只对页面的特定部分进行操作。或者,当它运行时,它应该“标记”它影响的每个元素,然后在应用新事件处理程序之前检查该标记。这样,它只会影响新加载的代码。(不过,缩小搜索范围会更有效;表达式$('.drag')
可能必须查看页面上的每个DOM元素,因此最好使用更精确的内容。)您没有发布任何HTML标记,也没有发布“AjaxementCall”的详细信息函数确实如此。因此,很难说你应该如何解决这个问题。但是,在每次“drop”事件中,您都会再次调用“dragDrop()”设置函数。您说“ajaxElementCall”重新加载页面的某些部分,但您的“dragDrop()”代码总是在页面上的所有元素上安装新的事件处理程序。如果“ajaxElementCall”只更新了页面的一部分,那么所有未更改的“.drag”和“.drop”元素都会堆积额外的事件处理程序
当您为某些选择器调用.click()
或.hover()
时,jQuery会将您提供的事件处理程序添加到已注册的处理程序集中。因此,因为每次调用“dragDrop()”时都要注册新的事件处理程序,所以会越来越多地堆积起来。当事件发生时,所有这些处理程序都将运行
可能您需要做的是更改“dragDrop()”,这样您就可以告诉它只对页面的特定部分进行操作。或者,当它运行时,它应该“标记”它影响的每个元素,然后在应用新事件处理程序之前检查该标记。这样,它只会影响新加载的代码。(不过,缩小搜索范围会更有效;表达式$('.drag')
可能必须查看页面上的每个DOM元素,因此最好使用更精确的内容。)首先,您应该开始使用比未排序的数组更好的数据结构来跟踪事物