Jump to content
Дизайн и модификация IPS Community IPBSkinsBETA
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
TemKa_SD

Перенос html с помощью JS

Recommended Posts

Здравствуйте, необходимо реализовать функцию, которая, переносит HTML в новое место, точнее, это старая логика, сейчас нужно придумать более сложный способ.

 

И так, вот старая функция:

 

var row = this.scope.find('[data-gamename="'+ data.gamename +'"] > .ipsDataItem_main > ul.ipsDataItem_subList');
var currentPlayer = row.find('[data-player="'+ data.name +'"]');
var currentSID = currentPlayer.parent();

var newSID = row.find('> li.usercolor.usercolor-'+ data.sid +'');
var newPlayer = newSID.innerHTML;

currentSID.html(newPlayer);
newSID.html(currentPlayer);

 

Она переносила пользователя на новый SID, например, с 0 на 5, а 5 на 0, там уже была структура li элементов, сейчас её нет, li нужно создавать через JS, поэтому, прошлый способ не подходит.

 

Я вот начал, но этого мало, оно переносит на новый SID но старый class остается:

 

this.scope.find('[data-gamename="'+ data.gamename +'"] > .ipsDataItem_main > ul.ipsDataItem_subList').find('[data-player="'+ data.name +'"]').removeClass('').addClass('usercolor usercolor-'+ data.sid +'');

 

Это функция входа игрока, в принципе в ней реализовано всё что нужно, нужно модифицировать под новые потребности и всё, сейчас буду пробовать, напишу что получилось или нет.

 

// Вход игрока
var rowElem = this.scope.find('[data-gamename="'+ data.gamename+ '"] > .ipsDataItem_main > ul.ipsDataItem_subList');
var playerElement = '<li class="usercolor usercolor-'+ data.sid +'" data-player="'+ data.name +'"><a href="#" data-ipsHover data-ipsHover-width="225" data-ipsHover-target="'+ ips.getSetting('baseURL') +'index.php?app=wc3&module=activegames&controller=ActiveGames&player='+ data.name +'&server='+ data.realm +'&ping='+ data.ping +'&do=hovercard" data-ipsHover-timeout="0">'+ data.name +'</a></li>';

var insertAfter, insertBefore, uColor;
var sid = data.sid;

rowElem.find('.usercolor').each(function( i ) {
   uColor = parseInt($(this).attr('class').replace('usercolor usercolor-', ''));

   if (uColor > sid && !insertBefore) {
       insertBefore = $(this);
   }

   if (uColor < sid) {
       insertAfter = $(this);
   }

});

if (insertAfter) {
   insertAfter.after(playerElement);
} else if (insertBefore) {
   insertBefore.before(playerElement);
} else {
rowElem.html(playerElement);
}

 

Как я примерно это вижу, у нас известен только новый SID, сначала необходимо спарсить старый. Затем, старый заменить на новый и наоборот, при этом, нужно сохранить последовательность li элементов.

Edited by TemKa_SD

Share this post


Link to post
Share on other sites

Парсит норм: http://prntscr.com/ms5xke

 

var currentSID = this.scope.find('[data-gamename="'+ data.gamename+ '"] > .ipsDataItem_main > ul.ipsDataItem_subList').find('[data-player="'+ data.name +'"]');
var uColor = parseInt(currentSID.attr('class').replace('usercolor usercolor-', ''));
var newSID = data.sid;

Debug.log("Старый SID: " + uColor + " Новый SID: " + newSID);

 

Он парсится, почему ошибка?

 

TypeError: Cannot read property 'replace' of undefined

 

Наверно, лучше всего будет удалить старый li и добавить новый.

Edited by TemKa_SD

Share this post


Link to post
Share on other sites

Здравствуйте. Вернулся к разработке данного приложения, последний вопрос актуален.

 

Я реализовал функцию замены данных при переходе игрока на другой слот, должен меняться li элемент на новый, в итоге получилось следующее (специально перед этим сообщением добавил комментарии в код):

 

handlePlayerChangedSID: function (data) {
// Определяем строку (игру) в которой нужно произвести замену.
var rowElem = this.scope.find('[data-gamename="'+ data.gamename+ '"] > .ipsDataItem_main > ul.ipsDataItem_subList');
// Определяем на каком слоте сейчас находится нужный игрок.
var currentColor = parseInt(this.scope.find('[data-gamename="'+ data.gamename+ '"] > .ipsDataItem_main > ul.ipsDataItem_subList').find('[data-player="'+ data.name +'"]').attr('class').replace('usercolor usercolor-', ''));
// Данные для замены (полностью li, нужно будет вывести эти данные в общую переменную, так как они используются в нескольких местах)
var playerElement = '<li class="usercolor usercolor-'+ data.sid +'" data-player="'+ data.name +'"><a href="#" data-ipsHover data-ipsHover-width="225" data-ipsHover-target="'+ ips.getSetting('baseURL') +'index.php?app=wc3&module=activegames&controller=ActiveGames&player='+ data.name +'&server='+ data.realm +'&ping='+ data.ping +'&do=hovercard" data-ipsHover-timeout="0">'+ data.name +'</a></li>';

var insertAfter, insertBefore, uColor;

rowElem.find('.usercolor').each(function( i ) {
	// Парсим старый sid слота, с которого ушел данный игрок.
    uColor = parseInt($(this).attr('class').replace('usercolor usercolor-', ''));

    // Если старый слот больше нового, вставить данные до старого слота.
    if (uColor > data.sid && !insertBefore) {
        insertBefore = $(this);
    }

    // Если старый слот меньше нового, вставить данные после старого слота.
    if (uColor < data.sid) {
        insertAfter = $(this);
    }

});

if (insertAfter) {
	// Если вставить после, выполняем функцию after и удаляем старый li.
    insertAfter.after(playerElement);
    this.scope.find('[data-gamename="'+ data.gamename +'"] > .ipsDataItem_main > ul.ipsDataItem_subList').find('li.usercolor.usercolor-'+ currentColor +'').remove();
} else if (insertBefore) {
	// Если вставить до, выполняем функцию before и удаляем старый li.
    insertBefore.before(playerElement);
    this.scope.find('[data-gamename="'+ data.gamename +'"] > .ipsDataItem_main > ul.ipsDataItem_subList').find('li.usercolor.usercolor-'+ currentColor +'').remove();
} else {
	// Если ни то ни то, вставляем просто html.
	rowElem.html(playerElement);
}
}

 

Здесь мне не понятно, зачем тут && !insertBefore:

 

    // Если старый слот больше нового, вставить данные до старого слота.
    if (uColor > data.sid && !insertBefore) {
        insertBefore = $(this);
    }

 

И ошибка в консоли: ypeError: Cannot read property 'replace' of undefined

 

На строку:

 

var currentColor = parseInt(this.scope.find('[data-gamename="'+ data.gamename+ '"] > .ipsDataItem_main > ul.ipsDataItem_subList').find('[data-player="'+ data.name +'"]').attr('class').replace('usercolor usercolor-', ''));

Share this post


Link to post
Share on other sites

Здесь мне не понятно, зачем тут && !insertBefore:

Очевидно для того, чтобы присвоить первый найденный элемент а не последний. Нам откуда знать зачем вы его там добавили.

 

Даже если бы я был автором этого кода, я бы не разобрался в нем без полноценной рабочей версии где можно в "живую" увидеть логику работы скрипта. Проблема то в чем?

 

И ошибка в консоли: ypeError: Cannot read property 'replace' of undefined

Скорее всего один из найденных элементов не имеет атрибута class.

Share this post


Link to post
Share on other sites

1. Плохой код?

2. Проблем в ошибке Error: Cannot read property 'replace' of undefined, оно всё работает, но ошибок не должно быть в консоли. class есть у всех, на демо нужно самому прыгать по слотам, чтобы увидеть логику, попробую скринами:

 

Вот я только зашел в игру и попал на 0 слот: http://prntscr.com/n8jwkb http://prntscr.com/n8jwnq

Вот я в игре перешел на другой слот (начинает работать выше указанная функция): http://prntscr.com/n8jwuq http://prntscr.com/n8jwxb т.е удалился старый li с usercolor-0 и добавился новый с usercolor-1, возможно не может найти class после удаления usercolor-0 хотя врятли, он удаляется в конце функции, в этот момент уже usercolor-1 существует.

 

3. Вопрос на засыпку, часа два копаюсь уже, не могу решить.

 

У меня есть два ol с разными data-role: http://prntscr.com/n8jxlk мне нужно найти data-gamename именно в data-role="lobbyRows", уже по разному пробовал, и через this.scop.find и через find и через this.scop.find.leight, не получается.

 

Я вроде правильно всё делаю, но чего-то не хватает.

 

if (this.scope.find('[data-role="lobbyRows"] > [data-gamename="'+ data.gamename +'"]')) {
Debug.log("ЛОББИ");
}
if (this.scope.find('[data-role="gameRows"] > [data-gamename="'+ data.gamename +'"]')) {
Debug.log("GAME");
}

 

if ($('[data-role="lobbyRows"]').find('[data-gamename="'+ data.gamename +'"]')) {
Debug.log("ЛОББИ");
}
if ($('[data-role="gameRows"]').find('[data-gamename="'+ data.gamename +'"]')) {
Debug.log("GAME");
}

Share this post


Link to post
Share on other sites

Блин, разобрался. У меня это действие стояло в начале функции:

 

this.scope.find('[data-gamename="'+ data.gamename +'"]').remove();

 

И когда выполнялись следующие условия, на странице уже не было игры, надо перенести в самый конец. Хоть в JS начал понимать немного, осталось функции выучить и синтаксис )))

 

-----------------

 

Еще у меня такой вопрос созрел, в правильности кода. Ситуация следующая: у меня один и тот же JS файл обновляет контент на странице в нескольких виджетах: игры, фильтр, статистика. Стоит ли делать условие на проверку существования виджетов? По идее, да, но на практике может это и будет лишним.

 

Т.е JS:

 

если на странице найден ID виджета со статистикой, выполняем условие. В условии код. По логике, если условие такое НЕ делать, при синтаксическом анализе браузер будет постоянно читать код всей функции. Если условие сделать, браузер остановит чтение ну или анализ на условии и дальше читать не будет. или я бред говорю?

 

Ага, вот я похоже с этим столкнулся:

 

Если условие в if:

 

if (this.scope.find('[data-role="lobbyRows"] [data-gamename="'+ data.gamename +'"]').length) {
var lobbiesBefore = parseInt(this.scope.find('[data-countType="currentLobbies"]').attr('data-currentCount'));
Debug.log("Значение: " + lobbiesBefore);
}

 

js ищет данные именно в этом блоке: http://prntscr.com/n8klrh так как [data-gamename='+ data.gamename +'] находится в другом виджете совсем, он не может спарсить, при этом, одно соединение только читается.

 

Вот без if: http://prntscr.com/n8kmo8

 

var lobbiesBefore = parseInt(this.scope.find('[data-countType="currentLobbies"]').attr('data-currentCount'));
Debug.log("Значение: " + lobbiesBefore);

Edited by TemKa_SD

Share this post


Link to post
Share on other sites

Так, ладно, мне очень понравилась идея поиска виджета, работает всё супер. Выше указанный код тоже изменил, много лишнего было, но ошибка осталась, прошу помочь.

Чтобы не вставлять весь код, вот его часть, на которую ругается:

 

// Определяем строку (игру) в которой нужно произвести замену.
var rowElem = this.scope.find('[data-gamename="'+ data.gamename+ '"]');
// Определяем на каком слоте сейчас находится нужный игрок.
var currentColor = parseInt(rowElem.find('[data-player="'+ data.name +'@'+ data.realm +'"]').attr('class').replace('usercolor usercolor-', ''));
rowElem.find('li.usercolor.usercolor-'+ currentColor +'').remove();

 

Структура html: http://prntscr.com/n8pu70 http://prntscr.com/n8pujh я вот думаю, может потому что data-player находится после usercolor usercolor-.

Share this post


Link to post
Share on other sites

Опять скриншоты.

 

Вам же написали

я бы не разобрался в нем без полноценной рабочей версии где можно в "живую" увидеть логику работы скрипта.

 

я вот думаю, может потому что data-player находится после usercolor usercolor-.
Без разницы.

Share this post


Link to post
Share on other sites
Хорошо, просто хост бот тестовый, на нем игроков может не быть. https://dev.wc3.info/wc3/ActiveGames/

Страница умерла.

 

Проверяйте элемент перед .replace() или используйте try/catch

Share this post


Link to post
Share on other sites

ТС, я же вам указал по поводу ошибки. У одного из элементов отсутсвует аттрибут класс, поэтому возвращается null, ну и соотвественно при вызове replace у null получаете ошибку. В гугле легко ищется пояснение этой ошибки. Вам нужно добавить условие на hasAttr("class")

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...