Имеется страница, на которую через
load
подгружается блок с таблицей. И есть JavaScript который работает с динамической (на стороне клиента) сортировкой колонок в этой таблице. На локальной машине (с локальным сервером) все работает, но с сервера не хочет. Пробовал несколько способов:
Вариант 1
Решаем в лоб:
<div id="to_load">Сюда подгружаем таблицу рейтинга</div>
<script type="text/javascript">
$('#to_load').load('/stat/rating/profiles_rank/ #for_including1');
</script>
При этом на самой
'/stat/rating/profiles_rank/'
внутрь блока
#for_including1
помещен подгрузка скрипта:
<script src="/static/js/sortable-table.js" type="text/javascript"></script>
или сам скрипт целиком.
На локале работает, на сервере нет.
Вариант 2
Пробуем подгрузку JavaScriot только после завершения
load
:
<div id="to_load">Сюда подгружаем таблицу рейтинга</div>
<script type="text/javascript">
$('#to_load').load('/stat/rating/profiles_rank/ #for_including1', function () {
$.getScript('/static/js/sortable-table.js');
});
</script>
Из блока
#for_including1
убираем скрипт (хотя эти и ничего не меняет).
На локале работает, на сервере нет.
Вариант 3
Возможно, в предыдущем примере
load
сообщил что все ОК! но имел в виду, что загрузка возможна (url
'/stat/rating/profiles_rank/'
доступен и блок
'#to_load'
тоже), но сама загрузка завершена не была. Тогда вот так:
<div id="to_load">Сюда подгружаем таблицу рейтинга</div>
<script type="text/javascript">
$.when($('#to_load').load('/stat/rating/profiles_rank/ #for_including1')).then(function(){
$.getScript('/static/js/sortable-table.js');
})
</script>
На локале работает, на сервере нет.
Размышления 1
В логах локальной машины видно, что реально скрипт
'/static/js/sortable-table.js'
может загружаться как после получения таблицы
'/stat/rating/profiles_rank/'
, так и до него. На работоспособности это не сказывается.
При этом на сервере JavaScript явно загружается и частично отрабатывает: появляются метки сортировки и происходит инициализация таблицы (построчное
<tr>
-чтение таблицы, удаление и построчный вывод после первичной сортировки). Но дальше работать не желает.
Извращения:
Если ставить задержки для загрузки JavaScript, например вот так:
<script type="text/javascript">
$('#to_load').load('/stat/rating/profiles_rank/ #for_including1', function () {
setTimeout(function(){
$.getScript('/static/js/sortable-table.js');
}, 1000);
// alert('готово');
});
</script>
Вообще ничего и нигде не работает.
Размышления 2
Возможно дело в скрипте сортировки таблицы. Сам я его не придумывал, а модифицировал готовый. Но получилось так:
/**
* таблица со встроенной сортировкой
* /static/js/sortable-table.js
* Created 18.июл.2017.
* оригинальный скрипт взят из: https://bootsnipp.com/snippets/4OZQx
*/
(function (document) {
'use strict';
var LightTableSorter = (function (Arr) {
var _th, _cellIndex, _order = '';
function _text(row) {
return row.cells.item(_cellIndex).getAttribute("data-sort").toLowerCase().replace(".", "");
}
function _sort(a, b) {
var va = _text(a), vb = _text(b), n = parseInt(va, 10);
if (n) va = n, vb = parseInt(vb, 10);
return va > vb ? 1 : va < vb ? -1 : 0;
}
function _toggle() {
var c = _order !== 'asc' ? 'asc' : 'desc';
_th.className = (_th.className.replace(_order, '') + ' ' + c).trim();
_order = c;
}
function _reset() {
_th.className = _th.className.replace('asc', '').replace('desc', '');
_order = '';
}
function onClickEvent(e) {
if (_th && _cellIndex !== e.target.cellIndex) _reset();
_th = e.target;
_cellIndex = _th.cellIndex;
var tbody = _th.offsetParent.getElementsByTagName('tbody')[0], rows = tbody.rows;
if (rows) {
rows = Arr.sort.call(Arr.slice.call(rows, 0), _sort);
if (_order === 'asc') Arr.reverse.call(rows);
_toggle();
tbody.innerHtml = '';
Arr.forEach.call(rows, function (row){tbody.appendChild(row);});
}
}
return {
init: function () {
var ths = document.getElementsByTagName('th');
Arr.forEach.call(ths, function (th) {th.onclick = onClickEvent;});
}
};
})(Array.prototype);
document.addEventListener('readystatechange', function(){
if (document.readyState === 'complete') LightTableSorter.init();
}, false);
})(document);
Понимаю его только отчасти. Но очевидно, что
LightTableSorter.init();
происходит. Возможно, что
onclick
конфликтует с чем-то, но почему он не конфликтует на подгружаемой странице
'/stat/rating/profiles_rank/'
где все тоже самое, просто загрузка скрипта стационарна, а не через
$.getScript
?
На всякий случай url странички где формируется таблица и все работает как надо:
https://oknardia.ru/stat/rating/profiles_rank/. И url c подгружаемом через
load
варианте, где работать не желает:
https://oknardia.ru/blogpost/17/Nagljadnoe-sravnen....
Собственно, пока идей нет, но проблему хочется решить.
UPD1: Заметил, что иногда в подгружаемом вариант скрипт все таки работает как положено. Примерно в 2-5% случаев. Почему??
UPD2: Оборачивание некоторых функций сортировщика в
try{...}cache(e){}
немного улучшило ситуацию. В частности:
document.addEventListener('readystatechange', function(){
// if (document.readyState === 'complete') LightTableSorter.init();
try{if (document.readyState === 'complete') LightTableSorter.init();}catch(e){}
}, false);
Но скорее всего дело все равно не в этом. На более развесистых DOM (например:
https://oknardia.ru/blog/P0) все равно не работает.