Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Меню Onclick (https://javascript.ru/forum/dom-window/1519-menyu-onclick.html)

Levin 06.08.2008 10:57

Меню Onclick
 
Как можно исправить меню выстроенное по событию onmouseover на меню раскрывающееся по клику, причем 2 и 3 подуровни ТОЖЕ ДОЛЖНЫ ОТКРЫВАТЬСЯ ПО КЛИКУ.
листинг :-)

navHover = function() {
	var lis = document.getElementById("navmenu").getElementsByTagName("LI");
	for (var i=0; i<lis.length; i++) {
		lis[i].onmouseover=function() {
			this.className+=" iehover";
		}
		lis[i].onmouseout=function() {
			this.className=this.className.replace(new RegExp(" iehover\\b"), "");
		}
	}
}
if (window.attachEvent) window.attachEvent("onload", navHover);

ZoNT 06.08.2008 11:15

onmouseover заменить на onclick :)

Levin 06.08.2008 13:41

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

ZoNT 06.08.2008 14:00

ну так в вопросе же было "на меню раскрывающееся по клику"
На закрывающееся по второму клику - в вопросе не было!

Учитесь правильно формулировать вопросы!!!

Levin 06.08.2008 14:30

причем 2 и 3 подуровни ТОЖЕ ДОЛЖНЫ ОТКРЫВАТЬСЯ ПО КЛИКУ.
(см. 1 сообщение темы).
Ладно, по существу, самому мне кажется что варианта нет, по крайней мере я не знаю.
Отсюда другой вопрос:
- как прописать в файле css (к этому меню), что бы меню усчезало не сразу после отвода мышки, а была задержка, т.к. проблема появилась из-за того, что меню исчезает сразу как убрали мышку, а менюха многоуровневая, большая.

ZoNT 06.08.2008 14:56

navHover = function() {
var lis = document.getElementById("navmenu").getElementsByTagName("LI");
for (var i=0,l=is.length; i<l; i++) {
  lis[i].onclick=function() {
    var reg = /iehover$/;
    if (reg.test(this.className))
      this.className=this.className.replace(reg, "");
    else this.className+=" iehover";
  }
}
}
if (window.attachEvent) window.attachEvent("onload", navHover);

Levin 06.08.2008 15:13

Цитата:

Сообщение от ZoNT (Сообщение 4221)
for (var i=0,l=is.length; i<l; i++) {

В условии точно все верно?

ZoNT 06.08.2008 16:06

for (var i=0,l=lis.length; i<l; i++) {

естественно lis, а не is

Levin 06.08.2008 18:14

Блин, все вроде написано правильно и красиво, просмотрел вроде все отлично выглядит, а на деле как то ничего не происходит, меню вообще не реагирует

ZoNT 06.08.2008 18:33

ну кинь ссылку на страничку, я посмотрю, где что глючит...

Levin 06.08.2008 19:37

Вложений: 1
У меня скрипт в файле находится. Держи вложение (это с сайта) файл ie.js

ZoNT 06.08.2008 21:52

и что, где я его в работе смотреть буду???

Levin 06.08.2008 23:16

Всмысле где? Там же файл index в нем непосредственно ссылка на ie.js (лежит рядом), а там сам код. Запустить в браузере и все. или я что то понял не так?

ZoNT 07.08.2008 00:10

navHover = function() {
	var lis = document.getElementById("navmenu").getElementsByTagName("LI");
	for (var i=0,l=lis.length; i<l; i++)
		lis[i].onclick=function() {
			window.event.cancelBubble = true;
		    var reg = /iehover$/;
		    if (reg.test(this.className))
				this.className=this.className.replace(reg, "");
		    else this.className+=" iehover";
		}
}

if (window.attachEvent) window.attachEvent("onload", navHover);



И подключай скрипт не используя условные комменты:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Испанская напольная плитка для ванной, итальянская облицовочная плитка, керамическая плитка Испания, стеклянная мозаика, керамогранит Италия - ALL DECO</title>
<link rel="stylesheet" href="design.css" type="text/css" />
<link rel="stylesheet" href="menu.css" type="text/css" />
<script src="ie.js" type="text/javascript"></script>

Они тебе не нужны, так как скрипт выполнится только в ИЕ

Levin 07.08.2008 11:39

Понятно, я чего то подобного добивался с помощью onMouseEnter и onMouseDown, но та же проблема, открытые элементы меню не закрываются при выборе другого элемента меню, их нужно закрывать повторным нажатием. В итоге получается куча мала друг на друге. С этим можно бороться?

ZoNT 07.08.2008 12:30

можно. Пиши скрипт, запоминай кто открыт, на каком уровне, закрывай при клике на другом элементе того же уровня и т.д. и т.п.

или ты хочешь, чтобы мы за тебя скрипты писали?

Levin 07.08.2008 13:59

Нет. Просто надеялся что есть способ при клике на элемент меню закрывать все остальные. Подобный обраец я делал и ранее.

ZoNT 07.08.2008 14:10

Есть способ: написать такой скрипт.

Levin 07.08.2008 17:23

Замечательно.
А скажи, что надо вставить в этот код, что бы меню закрывалось не сразу после отвода мышки от элемета?

ZoNT 07.08.2008 18:02

вешаешь закрытие (смену класса) на таймаут и всё (смотри setTimeout)

Levin 18.08.2008 17:35

У меня по непонятной причине setTimeout вообще никаких движений не производит, пробовал уже просто в функцию его вставить, ноль реакции
lis[i].onmouseout=function() {
			setTimeout("alert('gbhh')",3000);
			this.className=this.className.replace(new RegExp(" iehover\\b"), "");

Андрей Параничев 18.08.2008 17:48

Levin,
У вас ошибка где-то в другом месте, потому что вызов:
setTimeout("alert('gbhh')",3000);

Работает.

Levin 18.08.2008 17:52

Упс, извеняюсь, он в Firefox не работает почему то, в IE работает. Но от этого не легче. Мне надо вставить, насколько я понимаю, setTimeout в строку
this.className=this.className.replace(new RegExp(" iehover\\b"), "");

я прав?

ZoNT 18.08.2008 18:33

Цитата:

Сообщение от Levin (Сообщение 4691)
У меня по непонятной причине setTimeout вообще никаких движений не производит, пробовал уже просто в функцию его вставить, ноль реакции
lis[i].onmouseout=function() {
			setTimeout("alert('gbhh')",3000);
			this.className=this.className.replace(new RegExp(" iehover\\b"), "");

lis[i].onmouseout=function() {
		setTimeout("alert('gbhh')",3000);
		this.className=this.className.replace(/ iehover\b/, "");
}


Должно работать!

Levin 18.08.2008 19:08

To ZoNT: поздравляю с новой ученой степенью :-)
setTimeout работает (правда в Firefox не хочет, но это не важно пока).

Цитата:

Сообщение от ZoNT (Сообщение 4306)
вешаешь закрытие (смену класса) на таймаут и всё (смотри setTimeout)

Смена класса производится в строке
this.className=this.className.replace(new RegExp(" iehover\\b"), "");

, и setTimeout неодходимо внедрить сюда. Верно?

Андрей Параничев 18.08.2008 19:19

Levin,
Вам тут нужно будет применить хитрость, для передачи элемента в нужную область видимости:
lis[i].onmouseout = function() {
        setTimeout(function(element) {
            return function() {
                element.className=element.className.replace(/ iehover\b/, "");
            }
        }(this),3000);
}

Levin 18.08.2008 20:33

Ух, работает!!!
Спасибо большое, при 0,15 сек. вариант очень даже приемлемый!!!
Хитро, можно коментарии оставить, а то я немного запутался. Понять все таки хочется.

Андрей Параничев 18.08.2008 23:12

Levin,
// Обворачиваем функцию в локальное замыкание:
function(element) {
    // Возвращаем функцию, которая использует element
    // доступный в локальной области видимости:
    return function() {
        element.className=element.className.replace(/ iehover\b/, "");
    }
// Запускаем эту функцию с параметром this - текущий элемент
// теперь в setTimeout передана функция, которая вернулась
// по return
}(this);

Kolyaj 18.08.2008 23:16

Андрей Параничев, перемудрили что-то
lis[i].onmouseout = function() {
  var self = this;
  setTimeout(function() {
    self.className = self.className.replace(/ iehover\b/, "");
  }, 3000);
}

Андрей Параничев 19.08.2008 00:14

Kolyaj,
Не подумал, виноват :)

Levin 20.08.2008 17:48

Сколько много мнений сразу.
Спасибо огромное.


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