Перейти к публикации
View in the app

A better way to browse. Learn more.

Дизайн и модификация Invision Community

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

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

Опубликовано:

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

 

Заходит игрок на сервер на слот 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. При входе игрока заменять полностью строку а не самого игрока.

 

Какие мысли?

Рекомендованные сообщения

Опубликовано:

С нуллем в качестве значения чего либо лучше конечно не работать. Ну а так проверяйте на соответствие типа ===

Опубликовано:
  • Автор

Можно чуток подробней про соответствие типа?

Опубликовано:

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

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

 

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

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

Опубликовано:
  • Автор

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

 

Мне нужно добавить игрока в список, когда о его входе сообщает 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 вместе со слотом, когда заходит игрок, ведь нам известен слот на который он зашел и имя игры изанчально. Сейчас попробую.

Опубликовано:
  • Автор

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

 

		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 почти совсем не знаком.

Изменено пользователем TemKa_SD

Опубликовано:
  • Автор

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

Опубликовано:
  • Автор

Вот что-то вроде такого надо, только 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);
				}
			}

Изменено пользователем TemKa_SD

Опубликовано:
  • Автор

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

 

// Вход игрока
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

 

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

Изменено пользователем TemKa_SD

Опубликовано:

Стоит начать с прочтения того, что делает метод 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);
}
}

Опубликовано:
  • Автор

Спасибо, всё понял.

Опубликовано:
  • Автор

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

Изменено пользователем TemKa_SD

Опубликовано:

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

 

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

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

Опубликовано:
  • Автор

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

 

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

Изменено пользователем TemKa_SD

Опубликовано:
  • Автор

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

 

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.

 

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

 

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

Изменено пользователем TemKa_SD

Опубликовано:

Вроде все четко.

Создайте аккаунт или войдите в него для комментирования

Сейчас на странице 0

  • Нет пользователей, просматривающих эту страницу.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.