Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 26.06.2015, 13:06
Аспирант
Отправить личное сообщение для morg4n Посмотреть профиль Найти все сообщения от morg4n
 
Регистрация: 02.08.2010
Сообщений: 46

Проблема с фильтрацией динамических данных
По интервалу 5мин аяксом загружается tbody и подставляется в innerHTML таблице.
Потом есть input, который при keyup вызывает фукнцию, которая с помоощью цикла пробегает по queryselectorall("#table tbody tr") и прячет те, где match(regexp) не проходит.

Проблема заключается в том, что спустя пару часов поиск начианает работать ооооочень долго с подвисанием браузера.

Если проблема не типичная, выложу код.
Ответить с цитированием
  #2 (permalink)  
Старый 26.06.2015, 13:21
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,144

morg4n,
или ваша таблица или количество keyup увеличивается
Ответить с цитированием
  #3 (permalink)  
Старый 26.06.2015, 15:11
Аспирант
Отправить личное сообщение для morg4n Посмотреть профиль Найти все сообщения от morg4n
 
Регистрация: 02.08.2010
Сообщений: 46

Таблица весит +- 15кб. Размер ее не меняется, но данные могут обновлятся.
ТАм проблема начинается во время фильтрации, чем больше символов введено тем быстрее работает.
Ответить с цитированием
  #4 (permalink)  
Старый 26.06.2015, 15:31
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,144

morg4n,
нет кода - нет совета
Ответить с цитированием
  #5 (permalink)  
Старый 26.06.2015, 17:44
Аспирант
Отправить личное сообщение для morg4n Посмотреть профиль Найти все сообщения от morg4n
 
Регистрация: 02.08.2010
Сообщений: 46

инициализация
function ajgettptable(){
    jsDrawTpTable(httpget('/tptable'));
    //$('#tplist').dataTable();

m = {
    table: document.querySelectorAll("table#tplist tbody")[0], //tbody of main table
    tfoot: document.querySelectorAll("#tplist #tfoot")[0].querySelector("ul"), // ul with sample li for pagination
    page: 0, // human +1
    items_per_page: 20,
    sort_index: 1, //col
    sort_invert: 1,
    sort_index_default: 0,
    sort_type_default: "num_sort",
    search_str: "",
    fast_search: document.querySelector("#fast_search").value,
    data_url: "_list/name"
}
ths = document.querySelectorAll("table#tplist thead th")
hash = window.location.hash.match("(?!=page=)([0-9]+)/([0-9]+)(?:&search=([^&]+)||)(?:&sort=||)((.+)/([0-1])||)")
if(hash){
    m.page = parseFloat(hash[1])-1
    m.items_per_page = parseFloat(hash[2])
    if (hash[3]) {
        m.search_str = hash[3]
        table_search(m.table,m.search_str)
        document.querySelector("#fast_search").value = m.search_str
    }
    if (hash[5]){
        ths.forEach(function(el,index){
            if( el.getAttribute("data-name") == hash[5] )
                m.sort_index = index
        })
    }
    if (hash[6]){
        m.sort_invert = hash[5] == "1" ? 1 : -1
    }
}

//bind onclick call sort to all td in th

ths.forEach(function(el,col_num){
    el.addEventListener("click", function(){
        table_sort(m.table, col_num)
        table_paginate(m.table, m.page)
    });
})

//bind fast search to input
document.querySelector("#fast_search").addEventListener("keyup",function(){table_search(m.table,this.value)})
//bind select to items_per_page
//document.querySelector("#items_per_page").addEventListener("change",function(){
//    m.items_per_page=parseFloat(this.options[this.selectedIndex].innerHTML)
    m.items_per_page=parseFloat(15)
    table_paginate_init(m.tfoot)
    table_paginate(m.table, m.page)
    table_build_hash()
//})

//document.addEventListener("keydown", prevent_reload);

    }

Все остальное:
NodeList.prototype.forEach = Array.prototype.forEach;
var m={}
function isNum(str){
	return str > 0 || str < 0
}
function str_sort(astr,bstr){
	return m.sort_invert * astr.localeCompare(bstr)
}
function num_sort(astr,bstr){
	return m.sort_invert * (astr - bstr)
}
function table_sort(table_obj, col_num){
	m.sort_invert = m.sort_index == col_num ? -m.sort_invert : 1
	m.sort_index = col_num
	table_sort_arr = Array.prototype.slice.call(table_obj.children);  
	table_sort_arr.sort(function(a,b){
		astr = a.children[col_num].innerHTML
		bstr = b.children[col_num].innerHTML
		if(astr == bstr){
			astr = a.children[m.sort_index_default].innerHTML
			bstr = b.children[m.sort_index_default].innerHTML
			return window[m.sort_type_default](astr,bstr)
		}
		else if (isNum(astr) && isNum(bstr))
			return num_sort(astr,bstr)
		else 
			return str_sort(astr,bstr)
	}).forEach(function (child) {   
	    table_obj.appendChild(child);  
	})
}


function table_paginate(table_obj, page_num){
	items_count = 0;
	m.page = page_num
	page_offset = page_num * m.items_per_page

	table_items = table_obj.querySelectorAll("tr:not(.search-hidden)")
	if(table_items.length <= page_offset)
		page_offset = table_items.length - 20
	if(page_offset <0)
		page_offset=0
	for(var i=0; i<table_items.length;i++){
    if(i>=page_offset && i<page_offset+m.items_per_page)
		table_items[i].classList.remove("page-hidden")
	else
		table_items[i].classList.add("page-hidden")
	}
	m.tfoot.querySelectorAll("li").forEach(function(el){el.classList.remove("active")})
	m.tfoot.children[m.page].classList.add("active")
	table_build_hash()
}


function table_search(table_obj,search_str){
	table_items = table_obj.children
	m.search_str = search_str
	str=m.search_str.toLowerCase().trim() // прячем !
	if (m.search_str.length < 2 && m.search_str.length > 0) return true;
	if(search_str && search_str[0] == "!"){
		str=str.substring(1) // прячем !
		m.search_type = 2 //data attr
		}
	else {
		m.search_type = 1 //td.innerHTML
		}

	//Костыли велосипеды (алфавит для регекспов + реги)
	var trans_1={"`":"ё","~":"ё",z:"я",x:"ч",c:"с",v:"м",b:"и",n:"т",m:"ь",",":"б","<":"б",".":"ю",">":"ю",a:"ф",s:"ы",d:"в",f:"а",g:"п",h:"р",j:"о",k:"л",l:"д",";":"ж",":":"ж","\\":"э","|":"э",q:"й",w:"ц",e:"у",r:"к",t:"е",y:"н",u:"г",i:"ш",o:"щ",p:"з","[":"х","{":"х","]":"ъ","}":"ъ"," ":" ","-":"-",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},trans_2={z:"з",x:"х",c:"ц",v:"в",b:"б",n:"н",m:"м",a:"а",s:"с",d:"д",f:"ф",g:"г",h:"х",j:"ж",k:"к",l:"л",q:"к",w:"в",e:"е",r:"р",t:"т",y:"у",u:"у",i:"и",o:"о",p:"п"," ":" ","-":"-",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"};var str_1="",str_2="";for(var i=0;i<str.length;i++){str_1+=trans_1[str[i]];str_2+=trans_2[str[i]]}regexp=new RegExp(str,"gi");regexp_1=new RegExp(str_1,"gi");regexp_2=new RegExp(str_2,"gi")
	for(var i=0; i<table_items.length;i++){
		reg = /data\-[a-z]+.{3}([^\"]+)\"/gi
		if(m.search_type == 2){ //DATA
			search_html = table_items[i].innerHTML //матчим все дата
			search_html = search_html.match(reg).join(" ") //в строку все сматченные дата
			}
		else { //SIMPLE TD CONTENT
			search_html = ""
			for(var y=0; y<m.table.children[i].children.length;y++){
				search_html += m.table.children[i].children[y].innerHTML //билдим строку с InnerHTML td
			}
		}
		if(search_html && (search_html.match(regexp) || search_html.match(regexp_1) || search_html.match(regexp_2)))
			table_items[i].classList.remove("search-hidden")
		else
			table_items[i].classList.add("search-hidden")
	}

	table_paginate_init(m.tfoot)
	table_paginate(m.table, m.page)
	table_build_hash()

}

function table_paginate_init(elem){
	line = elem.children[0]
	elem.innerHTML = ""
	pages = Math.ceil(m.table.querySelectorAll("tr:not(.search-hidden)").length / m.items_per_page)
	pages = pages == 0 ? 1 : pages
	m.page = m.page >= pages ? 0 : m.page
	for(var i=1;i<=pages;i++){
		line.querySelector("a").innerHTML = i
		page = i-1
		line.querySelector("a").href = "javascript:table_paginate(m.table,"+page+")"
		elem.innerHTML += line.outerHTML
	}
}

function prevent_reload() {
    switch (event.keyCode) {
        case 116 : // 'F5'
            event.preventDefault();
            event.keyCode = 0;
            console.warn("page refresh is prevented")	
            break;
       	 case 82 : //R button
            if (event.ctrlKey){ 
                event.preventDefault();
                event.keyCode = 0;
                console.warn("page refresh is prevented")
                break;
            }
    }
}

function table_build_hash(){
	page = m.page + 1
	search_hash = m.search_str ? "&search="+m.search_str : ""
	sort_invert_hash = m.sort_invert == 1 ? 1 : 0
	sort_hash = "&sort=" + ths[m.sort_index].getAttribute("data-name") + "/" + sort_invert_hash
	window.location.hash = "page="+(m.page+1)+"/"+m.items_per_page+search_hash+sort_hash
}

//load data
function load_data(){
    majax.get(m.data_url).success(function (data, xhr) {
        m.table.innerHTML = data
        m.sort_invert = -m.sort_invert
        table_sort(m.table, m.sort_index)
        table_search(m.table,m.fast_search)
        table_paginate_init(m.tfoot)
        table_paginate(m.table, m.page)
        table_build_hash()
    })
}


Данные которые подгружаются:
Код:
<div class="table-container" style="width: 100%">
<style>
    .page-hidden, .search-hidden {display:none;}
    tfoot nav a {cursor: pointer}
</style>

    <table class="table table-hover table-responsive" id="tplist" cellspacing="0" width="100%" >
        <thead>
            <tr>
                <th data-name="id">Номер</th>
                <th data-name="city">Город</th>
                <th data-name="name">Название</th>
                <th data-name="address">Адрес</th>
                <th data-name="ip">IP</th>
            </tr>
        </thead>
        <tbody class="list">
        
            <tr class="
            " style="cursor: pointer;" id="ofNum" onclick="ajgettpinfo(23)">
                <td data-state="open" data-ip="None"
                    data-inet="noinet"
                    data-region="Санкт-Петербург"
                    class="ofNum">None</td>
                <td class="city">Санкт-Петербург</td>
                <td class="ofName">Видео-центр</td>
                <td class="address" >Каменка</td>
            
                <td class="localip">77.77.77.77</td>
            
            </tr>
Ответить с цитированием
  #6 (permalink)  
Старый 26.06.2015, 23:19
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,144

morg4n,
строка 131
window.location.hash = "page="+(m.page+1)+"/"+m.items_per_page+search_hash+sort_hash
-- информация по возможной проблеме
animated hash
Ответить с цитированием
  #7 (permalink)  
Старый 29.06.2015, 09:36
Аспирант
Отправить личное сообщение для morg4n Посмотреть профиль Найти все сообщения от morg4n
 
Регистрация: 02.08.2010
Сообщений: 46

Пробовал использовать методику из приведенной вами ссылки
history.replaceState(history.state, document.title, location.href.replace(/#.*$/g, '') + '#' + line);

и просто закомментил эту строчку.
К сожалению не помогло.
Ответить с цитированием
  #8 (permalink)  
Старый 29.06.2015, 10:33
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,144

morg4n,
в консоли нужно смотреть какие функции занимают ресурсы
https://learn.javascript.ru/debugging-chrome
http://habrahabr.ru/post/149053/
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с асинхронной передачей данных через POST Kapitan79 AJAX и COMET 2 28.12.2013 11:47
проблема с передачей данных из файла в файл qwertycal Общие вопросы Javascript 7 20.01.2013 14:16
Двойная Фильтрация данных таблицы David0707 Общие вопросы Javascript 0 19.03.2012 13:00
ajax чат проблема с записью сообщения в базу данных mysql. Niksik AJAX и COMET 4 15.01.2012 14:04
jQuery.ajax( ) проблема пи получении данных от сервера hard0000 jQuery 4 30.07.2010 12:34