Перенос html с помощью JS - Дизайн и модификация Invision Power Board

Перейти к содержимому

 

СвернутьПрикрепленные теги

Теги не найдены

Страница 1 из 1

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

#1 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 562
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 02 Март 2019 - 09:21

Здравствуйте, необходимо реализовать функцию, которая, переносит 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 элементов.

Сообщение изменено: TemKa_SD (02 Март 2019 - 09:25)

0

#2 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 562
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 02 Март 2019 - 09:53

Парсит норм: 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 и добавить новый.

Сообщение изменено: TemKa_SD (02 Март 2019 - 10:03)

0

#3 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 562
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 06 Апрель 2019 - 09:51

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

Я реализовал функцию замены данных при переходе игрока на другой слот, должен меняться 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-', ''));

0

#4 Пользователь не на сайте   siv1987 ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins Team
  • Сообщений: 9 443
  • Регистрация: 20-Март 09
  • Репутация: 2 544
  • IPB version:3.1.x
 

Отправлено 06 Апрель 2019 - 10:44

Просмотреть сообщениеTemKa_SD сказал(а):

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

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

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

Просмотреть сообщениеTemKa_SD сказал(а):

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

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

#5 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 562
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 07 Апрель 2019 - 07:03

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");
}

0

#6 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 562
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 07 Апрель 2019 - 08:33

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

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);

Сообщение изменено: TemKa_SD (07 Апрель 2019 - 09:09)

0

#7 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 562
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 07 Апрель 2019 - 19:02

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

// Определяем строку (игру) в которой нужно произвести замену.
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-.
0

#8 Пользователь не на сайте   newbie ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins.ru Team
  • Сообщений: 3 729
  • Регистрация: 26-Октябрь 11
  • Репутация: 1 465
  • IPB version:I have no IPB
 

Отправлено 08 Апрель 2019 - 07:18

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

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

Цитата

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


Цитата

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

#9 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 562
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 14 Апрель 2019 - 14:06

Хорошо, просто хост бот тестовый, на нем игроков может не быть. https://dev.wc3.info/wc3/ActiveGames/
0

#10 Пользователь не на сайте   newbie ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins.ru Team
  • Сообщений: 3 729
  • Регистрация: 26-Октябрь 11
  • Репутация: 1 465
  • IPB version:I have no IPB
 

Отправлено 15 Апрель 2019 - 13:54

Просмотреть сообщениеTemKa_SD сказал(а):

Хорошо, просто хост бот тестовый, на нем игроков может не быть. https://dev.wc3.info/wc3/ActiveGames/
Страница умерла.

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

#11 Пользователь не на сайте   siv1987 ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins Team
  • Сообщений: 9 443
  • Регистрация: 20-Март 09
  • Репутация: 2 544
  • IPB version:3.1.x
 

Отправлено 15 Апрель 2019 - 14:07

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

Сообщить об этой теме:


Страница 1 из 1


Быстрый ответ

  

1 пользователей читают эту тему
0 зарегистрированных, 1 гостей, 0 скрытых


Контактная информация

Вопросы по работе сайта

+7 (917) 501-4765
C 10 до 20 в рабочие дни (время московское)

Техническая поддержка

Контактные данные специалистов

Дизайн форумов

IPB 3.x ¦ IPB 2.x

Бесплатные шаблоны

IPB 3.2 – 3.4 ¦ IPB 3.1 ¦ IPB 3.0 ¦ IPB 2.2 – 2.3 ¦ IPB 2.1 ¦ Клипарт
Лицензия на использование ¦ Ваша поддержка ¦ О проекте
Copyright © 2005-2019 IPBSkins.ru Team
При копировании материалов с сайта
прямая ссылка на источник обязательна