Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   изменение css с помощью js (https://javascript.ru/forum/misc/48102-izmenenie-css-s-pomoshhyu-js.html)

mixtape 19.06.2014 17:41

изменение css с помощью js
 
Добрый день!

Имеется следующий кусок HTML разметки:
<div id="underheader">
      <div class="main_center over">
      <ul>
        <li>
          <div class="thumb">
            <a rel="link" href="#"></a>
            <div class="overlay_corner"></div>
            <div class="overlay_title">Современная архитектура и красивый дизайн дома</div>
            <div class="overlay_like">4</div>
            <img src="content/1.jpg" alt=""/>
          </div>
          <div class="desc">
            <p class="date">Июнь 13, 2014</p>
            <p class="stats"><span class="comment">2</span><span class="like">4</span></p>
            <h1><a href="#" title="">Современная архитектура и красивый дизайн дома</a></h1>
          </div>
        </li>
       </ul>
     </div>
</div>

DIVы с классами "overlay_title", "overlay_like" и A (c rel=link) выполняют роль оверлэев и накладываются с помощью относительного позиционирования на картинку, следующую после них в структуре DOM-дерева. В CSS-файле данным DIVам указан visibility со значением hidden.
Задача простая до нельзя - нужно на событие наведения по гиперссылке (которая имеет атрибут rel со значение link) повесить анонимную функцию, которая бы переключала у этих двух DIVов свойство visibility на visible, при onmouseout сново на hidden.
Имеем следующий сценарий:
window.onload = function () {
  //UNDERHEADER
  var underheader = gi("underheader"), //underheader
      a = getNode(underheader, "A", "rel", "link"), //выборка области клика
      title = getNode(underheader, "DIV", "class", "overlay_title"), //выборка заголовочного оверлея
      like = getNode(underheader, "DIV", "class", "overlay_like"); //выборка оверлэя с кол-вом лайков
  for(var i = 0; i < a.length; i++) {
     a[i].onmouseover = function(){visible(title[i]); visible(like[i]);};
     a[i].onmouseout = function(){invisible(title[i]); invisible(like[i]);};
  }
};
//ф-я выборки узлов tag из obj по атрибуту atr и его значению val
function getNode(obj, tag, atr, val) {
  var el = gt(obj, tag),
      res = [];
  for(var i = 0; i < el.length; i++)
    if(el[i].getAttribute(atr) == val) res.push(el[i]);
  if(res.length) return res;
  return false;
}
//ф-я выборки по id
function gi(id) {
  return document.getElementById(id);
}
//ф-я выборки по tagname
function gt(obj, tag) {
  return obj.getElementsByTagName(tag);
}
function invisible(obj) {
  obj.style.visibility = "hidden";
}
function visible(obj) {
  obj.style.visibility = "visible";
}

При запуске консольки браузеров выдают такой error:
Код:

Uncaught TypeError: Cannot read property 'style' of undefined
Все узлы выбраны верно. Теперь меняем сценарий так, чтобы на события назначались функции не в цикле for, в ручную, то есть просто убираем цикл:
a[0].onmouseover = function(){visible(title[0]); visible(like[0]);};
a[0].onmouseout = function(){invisible(title[0]); invisible(like[0]);};

И вуаля всё работает, но само собой так делать бред, ибо таких блоков у меня много и они дёргаются из БД. Пробовал через addEventListener, выдаёт аналогичную ошибку:
Код:

Uncaught TypeError: Cannot read property 'addEventListener' of undefined
Такое ощущение, что какой-то косяк с областями видимости или что-то типо того, но убейте не могу понять, где я накосячил. Я чего-то не понимаю?

рони 19.06.2014 18:02

mixtape,
а скрипт вам зачем для этого?

mixtape 19.06.2014 18:37

рони,
а каким образом можно ещё реализовать? через hover в css не получится, тк надо отображать не тот элемент, на который навожусь (а навожу курсор на гиперссылку), а два других див блока, у которых z-index ниже, чем у гиперссылки, посему hover на каждый из див блоков не сработает.

рони 19.06.2014 18:54

mixtape,
css "overlay_title", "overlay_like" и A (c rel=link) покажите

mixtape 19.06.2014 19:00

рони,
#underheader .thumb {
  height: 140px;
  width: 100%;
}
#underheader .thumb a {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  z-index: 4;
}
#underheader .thumb .overlay_corner {
  position: relative;
  width: 100%;
  height: 100%;
  top: -140px;
  z-index: 3;
  background-image: url(../images/overlay_corner.png);
  background-repeat: no-repeat;
  background-position: 22% 100%;
}
#underheader .thumb .overlay_title {
  position: relative;
  width: 190px;
  height: 110px;
  background-color: rgba(200,26,60,0.5);
  top: -280px;
  z-index: 1;
  padding: 30px 15px 0px;
  visibility: hidden;
}
#underheader .thumb .overlay_like {
  position: relative;
  width: 140px;
  height: 50px;
  padding: 90px 0 0 80px;
  background-image: url(../images/overlay_like.png);
  background-repeat: no-repeat;
  background-position: 20% 78%;
  top: -420px;
  z-index: 2;
  visibility: hidden;
}
#underheader .thumb img {
  position: relative;
  width: 220px;
  height: 100%;
  top: -560px;
  z-index: 0;
}

рони 19.06.2014 19:09

mixtape,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <style type="text/css">
  #underheader .thumb {
  height: 140px;
  width: 100%;
}
#underheader .thumb a {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  z-index: 4;
}
#underheader .thumb .overlay_corner {
  position: relative;
  width: 100%;
  height: 100%;
  top: -140px;
  z-index: 3;
  background-image: url(../images/overlay_corner.png);
  background-repeat: no-repeat;
  background-position: 22% 100%;
}
#underheader .thumb .overlay_title {
  position: relative;
  width: 190px;
  height: 110px;
  background-color: rgba(200,26,60,0.5);
  top: -280px;
  z-index: 1;
  padding: 30px 15px 0px;
  visibility: hidden;
}
#underheader .thumb .overlay_like {
  position: relative;
  width: 140px;
  height: 50px;
  padding: 90px 0 0 80px;
  background-image: url(../images/overlay_like.png);
  background-repeat: no-repeat;
  background-position: 20% 78%;
  top: -420px;
  z-index: 2;
  visibility: hidden;
}
#underheader .thumb img {
  position: relative;
  width: 220px;
  height: 100%;
  top: -560px;
  z-index: 0;
}


#underheader .thumb  [rel="link"]:hover ~ .overlay_title,#underheader .thumb [rel="link"]:hover ~ .overlay_like  {
       visibility : visible;
  }

  </style>
  <meta charset="utf-8">

</head>

<body>
<div id="underheader">
      <div class="main_center over">
      <ul>
        <li>
          <div class="thumb">
            <a rel="link" href="#"></a>
            <div class="overlay_corner"></div>
            <div class="overlay_title">Современная архитектура и красивый дизайн дома</div>
            <div class="overlay_like">4</div>
            <img src="content/1.jpg" alt=""/>
          </div>
          <div class="desc">
            <p class="date">Июнь 13, 2014</p>
            <p class="stats"><span class="comment">2</span><span class="like">4</span></p>
            <h1><a href="#" title="">Современная архитектура и красивый дизайн дома</a></h1>
          </div>
        </li>
       </ul>
     </div>
</div>
<div id="underheader">
      <div class="main_center over">
      <ul>
        <li>
          <div class="thumb">
            <a rel="link" href="#"></a>
            <div class="overlay_corner"></div>
            <div class="overlay_title">Современная архитектура и красивый дизайн дома</div>
            <div class="overlay_like">4</div>
            <img src="content/1.jpg" alt=""/>
          </div>
          <div class="desc">
            <p class="date">Июнь 13, 2014</p>
            <p class="stats"><span class="comment">2</span><span class="like">4</span></p>
            <h1><a href="#" title="">Современная архитектура и красивый дизайн дома</a></h1>
          </div>
        </li>
       </ul>
     </div>
</div>
</body>

</html>

mixtape 19.06.2014 19:23

рони,
действительно, что-то про множественный селектор я забыл. работает.
но соль в том, что это был частный случай. косяк в js где-то есть. просто выше есть button (который в nav), который отрабатывает роль toggle, скрывает/показывает родительский блок ul, в котором и расположены эти элементы li.
<div id="underheader">
      <div class="main_center over">
      <header>
        <button></button>
        <nav>
          <a class="current" href="#">месяц</a>
          <a href="#">полгода</a>
          <button></button>
        </nav>
      </header>
      <ul>
        <li>
          <div class="thumb">
            <a rel="link" href="#"></a>
            <div class="overlay_corner"></div>
            <div class="overlay_title">Современная архитектура и красивый дизайн дома</div>
            <div class="overlay_like">4</div>
            <img src="content/1.jpg" alt=""/>
          </div>
          <div class="desc">
            <p class="date">Июнь 13, 2014</p>
            <p class="stats"><span class="comment">2</span><span class="like">4</span></p>
            <h1><a href="#" title="">Современная архитектура и красивый дизайн дома</a></h1>
          </div>
        </li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
      </ul>
      </div>
    </div>


Посему для него аналогично прописываю:
window.onload = function () {
var underheader = gi("underheader"), //underheader
      buttonClose = gt(underheader, "BUTTON")[1], //выборка кнопки сворачивания
      ul = gt(underheader, "UL"); //блок сворачивания
buttonClose.onclick = function(){toggle(ul);};
};
function gi(id) {
  return document.getElementById(id);
}
function gt(obj, tag) {
  return obj.getElementsByTagName(tag);
}
function toggle(obj) {
  obj.style.display = (obj.style.display == 'none') ? '' : 'none';
}

Вся та же ошибка:
Uncaught TypeError: Cannot read property 'display' of undefined

Посему данная проблема по-прежнему актуальна)

рони 19.06.2014 19:40

mixtape,
строка 4 чего-то нехватает что есть строкой повыше

MallSerg 19.06.2014 20:01

Цитата:

Сообщение от mixtape
. ... через hover в css не получится, тк надо отображать не тот элемент, на который навожусь ... .

<style>
	#id1{	background: red;}
	#id1:hover  ~ #id2 { background: #238C00;}
	#id2 {	background: #FF00FF;}
</style>
<div class="on" id="id1">первый</div>
<div class="no_class">просто блок</div>
<div class="no_class">просто блок</div>
<div class="th" id="id2">Второй</div>

рони 19.06.2014 20:04

MallSerg,
а проверить свой код?


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