Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Отмена события действующего на строку таблицы при клике на определенной ячейке? (https://javascript.ru/forum/events/29848-otmena-sobytiya-dejjstvuyushhego-na-stroku-tablicy-pri-klike-na-opredelennojj-yachejjke.html)

Rig 13.07.2012 21:10

Отмена события действующего на строку таблицы при клике на определенной ячейке?
 
Прошу прощения если не очень грамотно сформулировал вопрос. Суть в следующем — на строки таблицы повешена определённая функция

<tr onclick=.... и т.д>
<td><a href=...>...</a></td>
<td>...</td>
...
</tr>

понятно, что функция срабатывает при клике в любой области строки, а вот как сделать чтобы, например, при щелчке в ячейке, где размещена ссылка, функция не срабатывала?

cyber 13.07.2012 21:28

при клике по ссылке или при клике по ячайке внутри которой ссылка?

Rig 13.07.2012 22:00

При клике на ячейке в которой ссылка (включая и ссылку, конечно).

lord2kim 13.07.2012 22:28

как вариант, добавьте в начало функции(-й), повешенной(-ых) на строки таблицы, что-то типа такого
function click_tr(e) {
   if (typeof(e.target.href) != "undefined") {
        return true;
   }
   //остальной код функции
}

oneguy 13.07.2012 22:28

Нужно повесить ещё обработчик на ячейку, содержащую ссылку, и в нём вызвать event.stopPropagation();

lord2kim 13.07.2012 22:31

Цитата:

Сообщение от oneguy (Сообщение 188605)
Нужно повесить ещё обработчик на ячейку, содержащую ссылку, и в нём вызвать event.stopPropagation();

и event.cancelBubble=true для IE

cyber 13.07.2012 22:31

вот так
<!DOCTYPE HTML>
<html>
  <head> 
  
    <style>
      td{
        width:50px;
        height:50px;
        border:1px solid black;
      }
    
    </style>
  </head>
  <body>
   
    <table id='tb'>
      <tr><td>1</td></tr>
    <tr><td>2</td></tr>
      <tr><td><a href='#'> 3</a></td></tr>
      <tr><td>4</td></tr>
    </table>
    <script>

      document.getElementById('tb').onclick = function (e){
       
         var target = e&&e.target || event.srcElement;
      
        if(target.tagName == 'TD'){
        
          search(target)
        
        } else if(target.tagName == 'A')alert('link');
        return false;
      }
        function search(elem){
         
           var tags = elem.getElementsByTagName('a');
          if(tags.length)return;
          alert('ссылок нет');
        }

    </script>

  </body>
</html>

oneguy 13.07.2012 22:39

Цитата:

Сообщение от lord2kim
event.cancelBubble=true для IE

Точнее, для IE<9. В IE 9 stopPropagation работает нормально.

Rig 13.07.2012 22:41

Ого, сколько вариантов! Сейчас буду все пробовать, спасибо всем за помощь. Отпишусь обязательно!

bes 13.07.2012 23:22

<style>
  td {
    border: solid 1px;
    cursor: pointer;
    padding: 1em;
  }
</style>
<table id="table">
  <tr>
    <td>нет ссылки</td>
    <td><a href="#">ссылка</a></td>
    <td>нет ссылки</td>
  </tr>
  <tr>
    <td>нет ссылки</td>
    <td><a href="#">ссылка</a></td>
    <td>нет ссылки</td>
  </tr>
<table>

<script>
window.onload = function () {
  var table = document.getElementById('table');

  table.onclick = function (e) {
    e = e || event;
    var target = e.target || e.srcElement;
    if (target.parentNode.tagName == 'TR') {
      if (target.innerHTML.search('href') == -1) {
        alert('здесь ссылки нет')
      } else {
        alert('ячейка со ссылкой')
      }
    } else if (target.tagName == 'A') {
      alert('ссылка')
    }
  }

}
</script>

Rig 13.07.2012 23:38

В моем случае, удобнее всего оказалось вот это:
<tr onclick=.... и т.д>
<td onclick="event.stopPropagation?event.stopPropagation():event.cancelBubble=true">

Кстати, пробовал cancelBubble в разных браузерах IE 8, Firefox 13.0.1, Chromium везде срабатывало, т.е. получается что если не бояться монстров пожирающих за плохой стиль програмирования, то можно было бы обойтись и без stopPropagation.

P/S: про оба эти свойства раньше не слышал, очень благодарен всем указавшим на них!

bes 15.07.2012 10:59

Кстати у cyber наверное самое универсальное решение для определения наличия ссылки в родительском контейнере: element.getElementsByTagName('a').length вернёт 0, если ссылок нет
PS:
Цитата:

Сообщение от cyber
if(tags.length)return;
alert('ссылок нет');

alert не сработает после return

cyber 15.07.2012 14:36

Цитата:

Сообщение от bes (Сообщение 188937)
Кстати у cyber наверное самое универсальное решение для определения наличия ссылки в родительском контейнере: element.getElementsByTagName('a').length вернёт 0, если ссылок нет
PS:
alert не сработает после return

да я писал я его в форме комментария вообще странно что он пашет.А насчет того что не правильно будет работать вы правы..
вот так правильно
if(element.getElementsByTagName('a')[0])

bes 15.07.2012 15:39

Цитата:

Сообщение от cyber
да я писал я его в форме комментария вообще странно что он пашет.А насчет того что не правильно будет работать вы правы..
вот так правильно
if(element.getElementsByTagName('a')[0])

Можно и так, но можно и через length.
Проверку наверное лучше сделать на равенство 0 (или undefined в последнем случае), так как иначе каждый раз будут осуществляться лишние проверки на неравенство пустой строке, null и undefined (не принципиально, конечно, но всё же).
PS: А срабатывает потому, что length коллекции всегда существует: если ссылок нет, то length равно 0 (если ссылки есть, то length > 0, поэтому проверка на неравенство 0 сработает, поэтому сработает return, а если ссылок нет, то проверка на неравенство 0 не сработает, следовательно, не сработает return, поэтому выполнится alert, так что этот способ рабочий, хотя может быть и несколько морочный для понимания).

cyber 15.07.2012 15:45

Цитата:

Сообщение от bes (Сообщение 188971)
Можно и так, но можно и через length.
Проверку наверное лучше сделать на равенство 0 (или undefined в последнем случае), так как иначе каждый раз будут осуществляться лишние проверки на неравенство пустой строке, null и undefined (не принципиально, конечно, но всё же).
PS: А срабатывает потому, что length коллекции всегда существует: если ссылок нет, то length равно 0 (если ссылки есть, то length > 0, поэтому проверка на неравенство 0 сработает, поэтому сработает return, а если ссылок нет, то проверка на неравенство 0 не сработает, следовательно, не сработает return, поэтому выполнится alert, так что этот способ рабочий, хотя может быть и несколько морочный для понимания).

вы меня самого запутали=)
кстати да оно правильно работает if(tags.length)return;

bes 15.07.2012 15:51

Цитата:

Сообщение от cyber
вы меня самого запутали=)

Да, всё чётко, это я сразу не совсем вник в ситуацию, пардон :), ТС просил отсечь ячейки со ссылками, return отсёк.

cyber 15.07.2012 17:42

Цитата:

Сообщение от bes (Сообщение 188974)
Да, всё чётко, это я сразу не совсем вник в ситуацию, пардон :), ТС просил отсечь ячейки со ссылками, return отсёк.

бывает:)

cyber 15.07.2012 17:50

Цитата:

Сообщение от Rig (Сообщение 188624)
<tr onclick=.... и т.д>
<td onclick="event.stopPropagation?event.stopPropagation():event.cancelBubble=true">

кстати мне кто то может объяснить как для отмены вызова функции в ячейках с ссылками, помогает отмена всплытия?:blink:

bes 15.07.2012 17:54

Цитата:

Сообщение от cyber
кстати мне кто то может объяснить как для отмены вызова функции в ячейках с ссылками, помогает отмена всплытия?

Если при клике на ячейку не будет всплытия, то не сработает обработчик клика на tr, который TC как раз и ставил

cyber 15.07.2012 17:59

это типо тс будет вешать в ручную обработчик на каждую ячейку где есть ссылка? (у меня конечно была такая мысль но она мне показалась сильно бредовой)

bes 15.07.2012 18:06

Цитата:

Сообщение от cyber
это типо тс будет вешать в ручную обработчик на каждую ячейку где есть ссылка? (у меня конечно была такая мысль но она мне показалась сильно бредовой)

ну это уже дело ТС :)

cyber 15.07.2012 18:11

//no comments
http://govnokod.ru/ :)


Часовой пояс GMT +3, время: 19:18.