Jump to content

Замена данных с помощью JS, помогите с логикой


TemKa_SD
 Share

Recommended Posts

Здравствуйте.

 

Заходит игрок на сервер на слот 0, чтобы вставились данные необходимо, в html указать этот идентификатор - 0, оно выглядит у меня так:

 

						{{foreach $game['players'] as $player}}
								<li class='usercolor usercolor-{{if isset($player['color'])}}{$player['color']}{{endif}}'></li>
						{{endforeach}}

 

где 0:

 

$player['color']

 

Ну и происходит замена через JS, здесь никаких проблем нет.

 

Вопрос в следующем, как идентифицировать слот 0 - если игрок еще не зашел и li еще нет в HTML.

 

Я вижу тут два варианта:

1. Изначально вывести пустые массивы слотов (оно существует стандартно, но я просил помочь убрать это тут: http://ipbskins.ru/forum/topic15826.html/page__view__findpost__p__106070), выглядит оно так: http://prntscr.com/mq0g6n

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

 

Какие мысли?

Link to comment
Share on other sites

Вообще ничего не понятно.

Какие-то запятые.

 

Что мешает убрать их с помощью css?

Данные появились -> добавили -> убрали скрытность

Link to comment
Share on other sites

Вопрос не в запятых, вот еще раз:

 

Мне нужно добавить игрока в список, когда о его входе сообщает Websocket. Чтобы правильно разместить игрока на его слоте и сделать замену, необходимо иметь вот этот код стандартно:

 

Массив слотов:

 

[players] => Array
(
   [0] => Array
       (
           [name] => 
           [realm] => 
           [ping] => 
           [color] => 0
       )

   [1] => Array
       (
           [name] => 
           [realm] => 
           [ping] => 
           [color] => 1
       )

   [2] => Array
       (
           [name] => 
           [realm] => 
           [ping] => 
           [color] => 2
       )

   [3] => Array
       (
           [name] => 
           [realm] => 
           [ping] => 
           [color] => 3
       )

   [4] => Array
       (
           [name] => 
           [realm] => 
           [ping] => 
           [color] => 4
       )

   [5] => Array
       (
           [name] => 
           [realm] => 
           [ping] => 
           [color] => 5
       )

)

 

В html это выглядит так:

 

<ul class="ipsDataItem_subList ipsList_inline userColorType-hellhalt">
   <li class="usercolor usercolor-0">

   </li>

   <li class="usercolor usercolor-1">

   </li>

   <li class="usercolor usercolor-2">

   </li>

   <li class="usercolor usercolor-3">

   </li>

   <li class="usercolor usercolor-4">

   </li>

   <li class="usercolor usercolor-5">

   </li>
</ul>

 

Мне это не нравится, и я попросил помощи убрать пустые массивы: http://ipbskins.ru/forum/topic15826.html/page__view__findpost__p__106070 всё стало как надо.

 

Теперь массив выглядит так:

 

Массив:

 

[players] => Array
   (
   )

 

HTML:

 

<ul class="ipsDataItem_subList ipsList_inline userColorType-hellhalt">
</ul>

 

Вот это правильный вариант, когда пустые слоты не выводятся нигде, а выводятся только тогда, когда зашел игрок.

 

Теперь вопрос, КАК вставить игрока на нужный слот через JS, если изначально в HTML слота нет.

 

Т.е сейчас метод следующий:

 

// Вход игрока
var rowElem = this.scope.find('[data-gamename="'+gamename+'"] > .ipsDataItem_main > ul.ipsDataItem_subList');
var rows = rowElem.find('> li.usercolor.usercolor-'+ data.sid +'');
var playerElement = '<a href="#" data-player="'+data.name+'" 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>';
rows.html(playerElement);

 

1. Находим именно ту игру, в которую зашел игрок.

2. Находим именно тот слот, на который зашел игрок.

3. Вставляем данные игрока в li именно этого слота.

 

Т.е, если изаначально слота нет в HTML структуре, то JS их не найдет.

 

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

 

Пока писал, пришла мысль, что можно полностью вставить li вместе со слотом, когда заходит игрок, ведь нам известен слот на который он зашел и имя игры изанчально. Сейчас попробую.

Link to comment
Share on other sites

Вроде получилось:

 

		var rowElem = this.scope.find('[data-gamename="'+gamename+'"] > .ipsDataItem_main > ul.ipsDataItem_subList');
		var playerElement = '<li class="usercolor usercolor-'+ data.sid +'"><a href="#" data-player="'+data.name+'" 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>';
		rowElem.html(playerElement);

 

Ладно, буду пробовать еще, есть глюки небольшие.

 

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

Edited by TemKa_SD
Link to comment
Share on other sites

Не получается, добавляется только один игрок, т.е игрок заходит на слот 1 - отображается, заходит второй игрок на слот 2 - первый игрок исчезает, второй отображается, без слотов никак?

Link to comment
Share on other sites

Вот что-то вроде такого надо, только rowElem.length размер какого элемента бы указать? Можно количество текущих игроков, но там пока тоже проблемы, не смог сделать.

 

		// Вход игрока
           var rowElem = this.scope.find('[data-gamename="'+gamename+'"] > .ipsDataItem_main > ul.ipsDataItem_subList');

			for( var i = 0; i < rowElem.length; i++ ){
				var playerElement = '<li class="usercolor usercolor-'+ data.sid +'"><a href="#" data-player="'+data.name+'" 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>';

				if( playerElement.length ){
					rowElem.html(playerElement);
				}
			}

Edited by TemKa_SD
Link to comment
Share on other sites

Получилось, всё проще чем казалось.

 

// Вход игрока
var rowElem = this.scope.find('[data-gamename="'+gamename+'"] > .ipsDataItem_main > ul.ipsDataItem_subList');
var playerElement = $('<li class="usercolor usercolor-'+ data.sid +'"><a href="#" data-player="'+data.name+'" 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>');
rowElem.append(playerElement);

 

Еще вот это нужно упорядочить как-то: http://prntscr.com/mqp7va

 

бред выше бы удалить, не позориться.

Edited by TemKa_SD
Link to comment
Share on other sites

Стоит начать с прочтения того, что делает метод html() http://api.jquery.com/html/#html2

Сперва у Вас

<ul class="ipsDataItem_subList ipsList_inline userColorType-hellhalt">
</ul>

 

Затем

<ul class="ipsDataItem_subList ipsList_inline userColorType-hellhalt">
   <li class="usercolor usercolor-1"></li>
</ul>

 

Затем

<ul class="ipsDataItem_subList ipsList_inline userColorType-hellhalt">
   <li class="usercolor usercolor-2"></li>
</ul>

 

Все внутри тегов

var rowElem = this.scope.find('[data-gamename="'+gamename+'"] > .ipsDataItem_main > ul.ipsDataItem_subList');
var playerElement = '<li class="usercolor usercolor-'+ data.sid +'"><a href="#" data-player="'+data.name+'" 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 uColor,
insertAfter = 0,
insertBefore = 0,
sid = parseInt(data.sid),
skip = false;

rowElem.find('.usercolor').each(function( i ) {
uColor = parseInt($(this).attr('class').replace('usercolor usercolor-', ''));
if (uColor == sid)
{
	skip = true;
	return false;
}

if (uColor > sid)
{
	insertBefore = uColor;
	return false;
}

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

if (skip == false) {
if (insertAfter > 0) {
	rowElem.find('.usercolor-' + insertAfter).after(playerElement);
} else if (insertBefore > 0) {
	rowElem.find('.usercolor-' + insertBefore).before(playerElement);
} else {
	rowElem.html(playerElement);
}
}

  • Upvote 1
Link to comment
Share on other sites

Блин, не могу разобраться, я попробовал со значениями в ручную - вроде вставляется, т.е я оставил игрока в игре с цветом 4, указал в ручную в JS для себя цвет 2 - встал перед ним, всё норм. Но автоматическая вставка не работает, наверно потому что у меня SID - 0 это реальный идентификатор в html, т.е слота идут с 0 1 2 3 .... Щас копаю еще...

Edited by TemKa_SD
Link to comment
Share on other sites

Копайте-копайте.

 

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

Изменил код. Проверьте

Link to comment
Share on other sites

Спасибо большое, всё супер. Сейчас буду разбираться что к чему )))

 

Хотя нет, есть баг. Я стоял на sid 2, зашел чел на sid 3 и заменил меня, но это из-за этого, буду еще копать. rowElem.html(playerElement);

Edited by TemKa_SD
Link to comment
Share on other sites

Так, я разобрался, в итоге получился следующий код:

 

var rowElem = this.scope.find('[data-gamename="'+gamename+'"] > .ipsDataItem_main > ul.ipsDataItem_subList');
var playerElement = '<li class="usercolor usercolor-'+ data.sid +'"><a href="#" data-player="'+data.name+'" 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 = parseInt(data.sid);
var skip = false;

rowElem.find('.usercolor').each(function( i ) {
   uColor = parseInt($(this).attr('class').replace('usercolor usercolor-', ''));
   if (uColor == sid) {
       skip = true;
       return false;
   }

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

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

});

if (skip == false) {
   if (insertAfter) {
   	Debug.log("Если uColor " + uColor + " < " + sid + " sid вставить после");
       insertAfter.after(playerElement);
   } else if (insertBefore) {
   	Debug.log("Если uColor " + uColor + " > " + sid + " sid вставить до");
       insertBefore.before(playerElement);
   } else {
	rowElem.html(playerElement);
}
}

 

С After всё работает отлично, а вот с before есть глюк. Дело в том, что, uColor выбирает максимальный текущий цвет, в случае с before это не подойдет, так как произойдет вставка ДО максимального слота, как на этом примере:

 

http://prntscr.com/mr05so

 

TemKa_SD я - захожу с SID 0.

Марихуана - последний максимальный слот SID 5.

 

Я встаю до этого слота, т.е всё работает как надо, код рабочий.

 

Единственное, мне нужно встать не до максимального слота, а до минимального, если я встаю ДО. Как пофиксить? )))) Я тут точно не разберусь, щас буду пробовать.

Edited by TemKa_SD
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...