Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery排序导致iOS Safari冻结_Javascript_Jquery_Xml_Sorting - Fatal编程技术网

Javascript jQuery排序导致iOS Safari冻结

Javascript jQuery排序导致iOS Safari冻结,javascript,jquery,xml,sorting,Javascript,Jquery,Xml,Sorting,我有一个使用jQuery加载XML文件的页面,然后将XML文件的内容输出到该页面 最近,我在输出中添加了一个排序功能,导致iPodtouch上Safari的挂起时间超过1分钟或2分钟(取决于我按多少字段排序),而iPad上的挂起时间不足1分钟。在Firefox4.0.1上,同样的排序会在几秒钟内返回 我担心这只是iOS的一个限制,但在我删除排序之前,也许可以进行优化 在筛选之前,XML中有357项。在过滤器之后,有199个项目被排序 var videoGames = $($.parseXML(v

我有一个使用jQuery加载XML文件的页面,然后将XML文件的内容输出到该页面

最近,我在输出中添加了一个排序功能,导致iPodtouch上Safari的挂起时间超过1分钟或2分钟(取决于我按多少字段排序),而iPad上的挂起时间不足1分钟。在Firefox4.0.1上,同样的排序会在几秒钟内返回

我担心这只是iOS的一个限制,但在我删除排序之前,也许可以进行优化

在筛选之前,XML中有357项。在过滤器之后,有199个项目被排序

var videoGames = $($.parseXML(videoGameXml)).find("game");
videoGames = videoGames.filter(function (a) {
    return ($(this).attr('addOn') != "true" && $(this).find('own').text() == "yes");
});
videoGames.sort(function (a, b) {
    var firstTitle = $(a).find('title').text().toLowerCase();
    var secondTitle = $(b).find('title').text().toLowerCase();
    var firstSystem = ($(a).find("console").text() + " " + $(a).find("version").text()).toLowerCase();
    var secondSystem = ($(b).find("console").text() + " " + $(b).find("version").text()).toLowerCase();

    if (firstSystem != secondSystem) {
        if (firstSystem > secondSystem) {
            return 1;
        } else {
            return -1;
        }
    } else {
        if (firstTitle > secondTitle) {
            return 1;
        } else if (secondTitle < firstTitle) {
            return -1;
        }
    }
    return 0;
});
videoGames.each(function () {
    // runs quickly, so removed
});
var videoGames=$($.parseXML(videoGameXml)).find(“游戏”);
视频游戏=视频游戏.过滤器(功能(a){
return($(this.attr('addOn')!=“true”和&$(this.find('own')).text()=“yes”);
});
视频游戏.排序(函数a,b){
var firstTitle=$(a).find('title').text().toLowerCase();
var secondTitle=$(b).find('title').text().toLowerCase();
var firstSystem=($(a).find(“控制台”).text()+“”+$(a).find(“版本”).text()).toLowerCase();
var secondSystem=($(b).find(“控制台”).text()+“”+$(b).find(“版本”).text()).toLowerCase();
if(第一个系统!=第二个系统){
如果(第一个系统>第二个系统){
返回1;
}否则{
返回-1;
}
}否则{
如果(第一标题>第二标题){
返回1;
}否则如果(第二标题<第一标题){
返回-1;
}
}
返回0;
});
视频游戏。每个(功能){
//跑得很快,所以被移除了
});
请注意,如果我将系统检查作为初始“优化”删除,它将iPod Touch上的时间减少一半,但仍然会导致上述1分钟以上的挂起

那么,这是一个iOS设备限制,还是我可以优化我的排序?

每次执行$(a)它都会执行一组非常复杂的操作,因此您最好将其缓存。此外,如果系统不同,则不需要标题。这个版本应该会加快一点速度:

videoGames.sort(function (a, b) {
    var first = $(a);
    var second = $(b);
    var firstSystem = (first.find("console").text() + " " + first.find("version").text()).toLowerCase();
    var secondSystem = (second.find("console").text() + " " + second.find("version").text()).toLowerCase();

    if (firstSystem != secondSystem) {
        if (firstSystem > secondSystem) {
            return 1;
        } else {
            return -1;
        }
    } else {
        var firstTitle = first.find('title').text().toLowerCase();
        var secondTitle = second.find('title').text().toLowerCase();

        if (firstTitle > secondTitle) {
            return 1;
        } else if (secondTitle < firstTitle) {
            return -1;
        }
    }
    return 0;
});
做:


您应该像这样移动任何选择器呼叫:

var firstTitle = $(a).find('title').text().toLowerCase();
从比较器函数中输出。比较器函数应该是轻量级的

使用
children()
扫描设置一次,在前面创建一个键数组,然后使用这些键对其进行排序


比较器函数将被调用
2n*ln(n)
次(取决于使用的算法),其中
n
是集合中的若干元素。因此,您的代码至少会执行两次相同的昂贵计算。

我本来打算回答相同的问题。您还可以缓存对象上的标题和系统,并仅在尚未检索到该对象时进行查找。Duh。当然,我不应该每次都这么做。您的初始版本将时间缩短了一半。詹姆斯,我认为这里的哈希表不是一个好主意。。编辑以将文本直接放入对象中。看看它是否能工作。看起来我必须先做
first.data('system',firstSystem)
而不是
first.data('system')=firstSystem
,但这确实把它缩短到了20秒左右。希望我能再投你一票,因为你已经给出了两个很好的答案。谢谢使用children()是一个很好的调用,但是你能澄清/扩展答案的第一部分吗?@James Skemp:扫描集合并为每个元素创建
el.attr(“数据键”,key)
。然后按该键进行
videoGames.sort()
。但是我怀疑您可以在列表元素本身上使用
数据标题
数据控制台
,等等属性。在这种情况下,排序根本不需要选择器。感谢您的澄清。iOS Safari似乎也在使用快捷方式排序数据,这也不值得。虽然Firefox 4.0.1以正确的顺序显示数据,但Safari在第一次排序时做得很好,但在标题上开始出现分歧(不一致-标题正在移动)。
var firstSystem = first.data('system');
if (!firstSystem) {
    firstSystem = (first.find("console").text() + " " + first.find("version").text()).toLowerCase();
    first.data('system') = firstSystem;
}
var firstTitle = $(a).find('title').text().toLowerCase();