Обработка событий с одинаковыми ID

302
03 февраля 2017, 06:08

Сделал незамысловатый живой поиск, и обработку перехода по списку по стрелкам вверх/вниз. Проблема в том, что по первому кругу всё проходит нормально, но если вернуться повторно в поле, то стрелочки начинают срабатывать через одну/две/и т.д. в зависимости от пройденных полей. В чем моя ошибка? Я уже пробовал задавать id в виде partn1..n pul1..n. Не понимаю работы JQ, если я обращаюсь по текущему this элементу, то почему на него влияют остальные текстовые поля???

И еще, как следствие, по Enter тоже начинает криво срабатывать, поле просто очищается.

$('tr[id^=add]').on("focus",'#partn',function(){ 
$partn = $(this); 
$pul = $(this).next().first(); 
$pul.find('li').first().addClass('act'); 
$pul.fadeIn();    
var inp = document.getElementById('partn'); 
inp.addEventListener("keydown", function(e) { 
    if (e.keyCode === 38 || e.keyCode === 40) e.preventDefault(); 
}, false); 
$partn.on("keyup", function(e) { 
	    switch (e.keyCode) { 
	    case 38: 
		$lc = $pul.find('li:visible').last(); 
        $fc = $pul.find('li:visible').first(); 
		if($fc.hasClass('act')) 
		{$fc.removeClass('act'); 
	     $lc.addClass('act'); 
		} else 
		{ 
		 $ac = $pul.find('li.act'); 
		 $ac.removeClass('act').prevAll(':visible:not(div)').first().addClass('act'); 
		} 
		break; 
		case 40: 
		$lc = $pul.find('li:visible').last(); 
        $fc = $pul.find('li:visible').first(); 
		if($lc.hasClass('act')) 
		{$lc.removeClass('act'); 
	     $fc.addClass('act'); 
		} else 
		{ 
		 $ac = $pul.find('li.act'); 
		 $ac.removeClass('act').nextAll(':visible:not(div)').first().addClass('act'); 
		} 
		break; 
		case 13: 
		$ac = $pul.find('li.act'); 
		$(this).val($ac.text()); 
		$ac.removeClass('act'); 
		$pul.fadeOut(); 
		break; 
		case 39: 
		case 41: 
		break; 
		default: 
		 
		if(!($pul).is(':visible')) $pul.fadeIn(); 
		$val = $(this).val().toUpperCase(); 
          $pul.find('li').each(function() { 
		  $(this).text().toUpperCase().indexOf($val)==-1?$(this).hide():$(this).show(); 
		  if($(this).hasClass('act')) $(this).removeClass('act'); 
		  }); 
		$pul.find('li:visible').first().addClass("act"); 
		break; 
		} 
		 
}); 
	$pul.on("click", "li", function(){ 
	    $partn.val($(this).text()); 
		$pul.find('li.act').removeClass('act'); 
	    $pul.fadeOut(); 
});   
}); 
$('tr[id^=add]').on("focusout",'#partn',function(){ 
	$pul = $(this).next().first(); 
	$pul.find('li.act').removeClass('act'); 
	$pul.fadeOut(); 
});
#pul { 
	position:absolute; 
	display:none; 
	z-index:109; 
	background: #FFF; 
	margin-top:2px; 
	    border: 1px #ccc solid; 
	    border-radius: 4px; 
	    max-height:200px; 
} 
#pul div { 
 display:block; 
 font-size:0.9rem; 
 font-weight:bold; 
 width:100%; 
 background-color:#eee; 
} 
#pul li { 
     list-style: none; 
	 font-size: 0.9rem; 
	 padding:2px 2px 2px 10px; 
     border-bottom: 1px #ccc solid; 
     cursor: pointer; 
     transition:0.3s;  
} 
li.act { 
  background-color:cornflowerblue; 
 color:#fff;   
} 
#pul li:hover{ 
	    background: #5a86d5; 
		color:#fff; 
	} 
#ul li:hover { 
    background-color: #eee;  
  }
<table> 
  <tr id=add1><td><input type=text id=partn /> 
    <ul id=pul> 
      <li>opt 1</li> 
      <li>apt 2</li> 
      <li>upt 3</li> 
      <li>cpt 4</li> 
      <li>ppt 5</li> 
    </ul> 
    </td></tr> 
  <tr id=add2><td><input type=text id=partn /> 
    <ul id=pul> 
      <li>opt 1</li> 
      <li>apt 2</li> 
      <li>upt 3</li> 
      <li>cpt 4</li> 
      <li>ppt 5</li> 
    </ul> 
    </td></tr> 
  <tr id=add3><td><input type=text id=partn /> 
    <ul id=pul> 
      <li>opt 1</li> 
      <li>apt 2</li> 
      <li>upt 3</li> 
      <li>cpt 4</li> 
      <li>ppt 5</li> 
    </ul> 
    </td></tr> 
</table> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

Answer 1

Не назначайте обработчики событий

inp.addEventListener("keydown", ...

и

$partn.on("keyup", ...

внутри других обработчиков событий

$('tr[id^=add]').on("focus",'#partn', ...

Они накапливаются и выполняются столько раз, сколько раз были назначены.

Ну и конечно, повторяющиеся id на странице - это грех. Используйте class.

READ ALSO
JQuery, функция resize()

JQuery, функция resize()

Есть элемент div с php-функцией внутри

316
Как в bootstrap 3 убрать затенение по краям carousel?

Как в bootstrap 3 убрать затенение по краям carousel?

Использую стандартный код отсюдаХочется убрать затенение

472
bootstrap c при помощи npm и webpack

bootstrap c при помощи npm и webpack

Я создал небольшое приложение и хочу подключить туда bootstrapВвожу команду:

821