#javascript #css #performance #responsive-design
#javascript #css #Производительность #адаптивный дизайн
Вопрос:
На ПК это работает хорошо. но для мобильных устройств уже слишком поздно. есть ли какой-либо другой более быстрый метод или другие?
function country_change(country,countries)
{
var cls = document.getElementsByClassName("country_events");
if(document.readyState == "loading")
{
alert('not loading.');
} else
{
for (n=0; n < cls.length; n )
{
var elem = cls[n];
var div_elem = elem.getElementsByTagName('div').length;
for (m=1; m < div_elem; m )
{
if (elem.getAttribute('name') == country)
{
if (elem.getElementsByTagName('div')[m].style.display == "none")
{
elem.getElementsByTagName('div')[m].style.display="block";
increaseHeight()
}
}
else
{
elem.getElementsByTagName('div')[m].style.display="none";
increaseHeight()
}
}
}
}
}
на ПК это работает около 1 ~ 3 секунд, но для мобильных устройств это занимает почти 10 ~ 20 секунд.
я думаю, что display — плохой метод, но другого способа нет, не так ли?
Комментарии:
1. Вы можете значительно оптимизировать цикл, удалив многие вызовы getElementsByClassName .
2. Из-за использования getElementByClassName это всего 20 ~ 30 объектов.
3. Конечно, но вы вызываете его 3 раза вместо одного раза. Это дорогостоящий метод для вызова и работы, поскольку это живой список узлов. Статическое использование cls тоже поможет. Это легкий большой выигрыш в производительности. Нет обещаний, что это будет очень быстро, но, вероятно, заметно быстрее.
Ответ №1:
Коллекция, возвращенная:
var cls = document.getElementsByClassName("country_events");
работает, поэтому для любого изменения DOM может потребоваться, чтобы браузер обновил коллекцию. Это может происходить намного чаще, чем вы думаете (и гораздо чаще в некоторых браузерах, чем в других), поэтому вы можете преобразовать это в массив или использовать querySelectorAll (который возвращает статическую коллекцию) вместо этого:
var cls = document.querySelectorAll(".country_events");
Тогда у вас есть:
var elem = cls[n];
var div_elem = elem.getElementsByTagName('div').length;
поэтому хорошо кэшировать elem, но getElementsByTagName также возвращает текущую коллекцию, поэтому снова используйте querySelectorAll:
var div_elem = elem.querySelectorAll('div').length;
div_elem кажется неподходящим именем, возможно, divCount было бы лучше?
Затем:
if (elem.getAttribute('name') == country)
вы можете сохранить вызов метода, обратившись к свойству напрямую:
if (elem.name == country)
И тогда ужасно бесполезно:
if (elem.getElementsByTagName('div')[m].style.display == "none")
{
elem.getElementsByTagName('div')[m].style.display="block";
increaseHeight()
Вы получили список divs ранее, поэтому кэшируйте его там
var divs = elem.querySelectorAll('div');
var divCount = divs.length;
Теперь повторно используйте его:
if (divs[m].style.display == 'none') {
divs[m].style.display = '';
} else {
divs[m].style.display = 'none';
}
increaseHeight();
который можно сократить до:
divs[m].style.display == divs[m].style.display == 'none'? '' : 'none';
increaseHeight();
Однако условный оператор обычно работает медленнее, чем эквивалентный if..else .
Таким образом, функция становится:
function country_change(country,countries) {
var cls = document.querySelectorAll('.country_events');
if(document.readyState == "loading") {
alert('not loading.');
} else {
for (var n=0, nLen=cls.length; n<nLen; n ) {
var elem = cls[n];
var divs = elem.querySelectorAll('div');
var divCount = divs.length;
for (var m = 1; m < divCount; m ) {
if (elem.name == country) {
if (divs[m].style.display == 'none') {
divs[m].style.display = '';
} else {
divs[m].style.display = 'none';
}
increaseHeight()
}
}
}
}
}
Обратите внимание, что querySelectorAll не поддерживается IE 7 и ниже.
Установка для element.style.display значения » (пустая строка) позволяет ему вернуться к своему стилю по умолчанию или вычисляемому стилю и означает, что вам не нужно знать, что это такое для каждого отдельного типа элемента или что включено в правила CSS.
Комментарии:
1. я последовал за вами, но (divs = elem. querySelectorAll(‘div’); div_elem[m].style.display), похоже, не может изменить отображение. это что-нибудь случится.