Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Динамическое изменение background-a в ячейках таблицы (https://javascript.ru/forum/events/6918-dinamicheskoe-izmenenie-background-v-yachejjkakh-tablicy.html)

Gh0stik 05.01.2010 16:35

Динамическое изменение background-a в ячейках таблицы
 
Доброе время суток.

Есть такая страничка:
<html>
<head>
  <link rel="stylesheet" href="css.css" type="text/css" />
  <title>Table</title>
</head>

<body>
<table class="tcolor">
<tr><th>Field 1</th><th>Field 2</th><th>Field 3</th></tr>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>3</td><td>5</td><td>7</td></tr>
<tr><td>5</td><td>8</td><td>11</td></tr>
<tr><td>7</td><td>11</td><td>15</td></tr>
</table>

<script language="JavaScript" src="change_gif.js" type="text/javascript"></script>
</body>
</html>


Соответственно стиль:
.tcolor {
	font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
	background-color: #CDCDCD;
	margin:10px 0pt 15px;
	font-size: 8pt;
	width: 100%;
	text-align: left;
}

.tcolor th {
    background-color: #99CCCC;
	background-image: url(c-red.gif);
	background-repeat: no-repeat;
	background-position: center right;
	cursor: pointer;
}


И сам скрипт:
document.onclick = function(evt)
{
  evt = evt || window.event;
  var el = evt.target || evt.srcElement;
  if ((el.tagName.toLowerCase() == "th") && (el.parentNode.parentNode.parentNode.className == "tcolor"))
  {
    with (el.style) {
      if (backgroundImage == "") {backgroundImage='url(c-red.gif)'; }

      p1 = backgroundImage.lastIndexOf('c-')+2;
      p2 = backgroundImage.lastIndexOf('.gif');
      imgName = backgroundImage.substr(p1, p2-p1);

      switch (imgName)
      {
        case 'red': backgroundImage = backgroundImage.replace('red','green'); break;
        case 'green': backgroundImage = backgroundImage.replace('green','yellow'); break;
        case 'yellow': backgroundImage = backgroundImage.replace('yellow','green'); break;
      }
    }
  }
}


По нажатию на заголовок таблицы происходит замена фоновой картинки ячейки. Но возник вопрос, как можно сделать так, чтобы при нажатии на очередной TH, стиль в "уже нажатой" (посещенном) ячейке изменялся на базовый, т.е. опять возвращался в url(c-red.gif);

И почему при первом обращении к свойству backgroundImage оно пустое? И мне приходится вручную его задавать
if (backgroundImage == "") {backgroundImage='url(c-red.gif)'; }

Как этого избежать? И как можно получить базовый стиль?
Пробовал его получить через el.style.cssText, но это свойство пустое :(.

Заранее спасибо за оказанную помощь.

Gh0stik 05.01.2010 16:37

И вообще насколько верно я обрабатываю событие нажатия на ячейку TH? Может есть другой более верный/простой способ?

Octane 05.01.2010 17:28

Цитата:

Сообщение от Gh0stik
И почему при первом обращении к свойству backgroundImage оно пустое?

Вы же берете одно из значений свойства el.style, которое изначально пустое
<tag style="…">…</tag>

Для обращения к вычисленным стилям получайте объект computedStyle (currentStyle в IE).

Цитата:

Сообщение от Gh0stik
И вообще насколько верно я обрабатываю событие нажатия на ячейку TH?

Верный способ, только событие onclick лучше начинать отлавливать на элементе <table>.

Gh0stik 05.01.2010 18:37

Спасибо за подсказку, вот исправил:
document.onclick = function(evt)
{
  evt = evt || window.event;
  var el = evt.target || evt.srcElement;
  if ((el.tagName.toLowerCase() == "th") && (el.parentNode.parentNode.parentNode.className == "tcolor"))
  {
    var elStyle = el.currentStyle || window.getComputedStyle(el, null);
    with (elStyle) {
      sValue = backgroundImage;
      p1 = sValue.lastIndexOf('c-')+2;
      p2 = sValue.lastIndexOf('.gif');
      imgName = sValue.substr(p1, p2-p1);

      switch (imgName)
      {
        case 'red': el.style.setProperty('background-image', sValue.replace('red','green'), "");  break;
        case 'green': el.style.setProperty('background-image', sValue.replace('green','yellow'), ""); break;
        case 'yellow': el.style.setProperty('background-image', sValue.replace('yellow','green'), ""); break;
      }
    }
  }
}

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


Цитата:

Сообщение от Octane
Верный способ, только событие onclick лучше начинать отлавливать на элементе <table>.

Не совсем понял, как это реализуется...

Есть ли возможность сделать так, чтобы при нажатии на очередной TH, стиль в "уже нажатой" (посещенном) ячейке изменялся на базовый, т.е. опять возвращался в url(c-red.gif);?

Octane 05.01.2010 19:20

Цитата:

Сообщение от Gh0stik
Но теперь не работает для IE, подскажите почему...

Какие ошибки выдает? p1, p2, imgName не надо через var записать? Может setProperty не поддерживает, зачем так сделали? В предыдущем коде el.style.backgroundImage = …; везде должно работать.

Цитата:

Сообщение от Gh0stik
Не совсем понял, как это реализуется...

Для каждого элемента <table> с CSS-классом tcolor добавить обработчик события onclick, а не для всего document.

Цитата:

Сообщение от Gh0stik
Есть ли возможность сделать так, чтобы при нажатии на очередной TH, стиль в "уже нажатой" (посещенном) ячейке изменялся на базовый, т.е. опять возвращался в url(c-red.gif);?

Ну в чем проблема, сохраняйте ссылку на измененный элемент и потом возвращайте его в исходное состояние. А лучше вообще не el.style менять, а просто CSS-класс (el.className).

Gh0stik 06.01.2010 00:54

Большое спасибо за замечания и советы. Все получилось!

SanaPo 09.02.2011 21:56

подскажите и че тут не так?

в <script languarge=JavaScript1.2><!-- ...--></script>,
mx.style.background="#ffcc88"; - работает
mx.style.backgroundImage='url(1.bmp)' - нет
mx.style.backgroundImage='url("1.bmp")' - нет
mx.style.background-Image='url(1.bmp)' - нет
ПОЧЕМУ?
mx-переменная id-шек <td>-шек

dmitriymar 09.02.2011 22:25

document.getElementById("....").style.backgroundImage = "1.bmp"

SanaPo 11.02.2011 18:39

<html>
<head></head>
<body>
<script><!--
document.write('Hello');
document.getElementById("one").style.backgroundIma ge = "1.bmp"
document.getElementById("two").style.backgroundIma ge = "2.bmp"
--></script>
<table border=1><tr>
<td id="one">info</td>
<td id="two">info</td>
</tr></table>
</body>
не пашет

NoResponse 11.02.2011 21:58

"не пашет" - и не должно
скрипт с таблицей местами поменяйте

mau 02.08.2012 16:52

Цитата:

Сообщение от Octane (Сообщение 39745)
Ну в чем проблема, сохраняйте ссылку на измененный элемент и потом возвращайте его в исходное состояние. А лучше вообще не el.style менять, а просто CSS-класс (el.className).

Простите за глупый вопрос, я только начинаю разбираться в js. Как сохранить ссылку на измененный элемент и потом вернуть его в исходное состояние. Заранее благодарен!

Deff 02.08.2012 17:48

mau,
Вообще - классически - это добавлять класс с прописанным новым стилевым оформлением в стилях - и удалять все данные классы при установке класса на новый элемент(хотя бывают причины не придерживацо классики, если делаем анимацию данных свойст не через css - а скриптом) или иной алгоритм

mau 02.08.2012 18:20

Это все хорошо. Но так как я только начинаю писать на js из ваших слов я понял лишь, что нужно:
а) добавить класс стилевого оформления;
б) удалить другие классы используемые элементом к которому я хочу применить класс созданный в пункте "а";
в) применить созданный в пункте "а" класс к нужному мне элементу;
Но я понятия не имею как сделать пункт "б". Это раз.
Во-вторых мне непонятно как применить класс к нужному мне элементу из обработчика события не связанного с этим элементом. В данном случае это строка таблицы.
Например я щелкаю один раз по строке. Событие onClick меняет цвет заливки. ОК. Я щелкаю по другой строке. Событие onClick меняет цвет заливки и возвращает цвет заливки предыдущей строки. Вот как поменять цвет заливки предыдущей строки мне собственно говоря и не понятно.

Deff 02.08.2012 18:29

mau,
С
Цитата:

Сообщение от mau
а) добавить класс стилевого оформления;

И б) При клике на новый элемент - убираем всюду добавленный исключительно данный класс
И ставим его только у текущего
Цитата:

Сообщение от mau
от как поменять цвет заливки предыдущей строки мне собственно говоря и не понятно.

В классе у Вас и прописан новый цвет заливки - убираете класс - возвращается исходная заливка

mau 02.08.2012 19:11

Цитата:

убираем всюду добавленный исключительно данный класс
Если не сложно элементарный пример можете показать. Достаточно двух строк. Например: add(class), removeall(class). Буду очень благодарен. Когда очень много незнакомого копать очень тяжело. Спасибо. Разобрался)

Deff 02.08.2012 19:40

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta content="text/html; charset=windows-1251" http-equiv="Content-Type">
<script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script>
</head>
<body style="text-align:center;padding-top:34px;">
<center>

<style>
table td {
  background:#3BDE3B;
}
table td.Active {
  background:#FC9090;
}
</style>

<table border='1'>
 <tbody>
   <tr>
      <td>ячейка 1</td><td>ячейка 2</td><td>ячейка 3</td>
  </tr>
     <tr><td>ячейка 4</td><td id=My>ячейка 5</td><td>ячейка 6</td>
  </tr>
  <tr>
     <td>ячейка 7</td><td>ячейка 8</td><td>ячейка 9</td>
  </tr>
 </tbody>
</table>

</center>
<script type="text/javascript">
$("table td").click (function() {
  $("table td").removeClass('Active');
  $(this).addClass('Active');
});
</script>


</body>
</html>


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