Встроенные стили, возникающие из ниоткуда
ВЕРСИЯ 1. РЕДАКТИРОВАННАЯ ВЕРСИЯ НИЖЕ
Это очень простое представление о том, что у меня изначально было, я не могу получить его короче, поэтому я извиняюсь за загрузку кода. Я прокомментировал, где проблема может лежать.
Расширенная скрипка: http://jsfiddle.net/BramVanroy/tKL8E/53/
Как видите, есть меню, которое можно навести. В обычном представлении (горизонтальное меню) появятся всплывающие подсказки, которые представляют заголовок ссылки (так что в основном это измененные подсказки). При изменении размера окна до < 800 меню должно стать вертикальным (медиазапросы). Проблема в том, что функция, которая была вызвана внутри if-функции, все еще работает. Модифицированная всплывающая подсказка продолжает появляться и анимироваться (вместо стандартных всплывающих подсказок), а стрелки по-прежнему располагаются.
function triangleMenu() {
var wW = $(window).width();
if (wW > 800) {
// Get rid of [title]'s and put them in data unless it has sub-items
$("li:not(.has-sub-menu) > a[title]").each(function () {
var $this = $(this);
$this.data("title", $this.attr("title"));
$this.removeAttr("title");
});
// tooltip positioning on hover and overlay fade on all li's
$("nav li").hover(function () {
// Bunch of vars
if (
($this.parent("ul:not(.sub-menu)").length || ($this.parent("ul.sub-menu").length && $this.is(":last-child"))) && !$this.hasClass("has-sub-menu")) {
tooltip.stop(true).css("right", "auto").text(title).animate({
"left": posL - (tooltip.width() / 2),
"top": posT + $this.offset().top + 20
}, 300).fadeTo(200, 1);
} else if (!$this.is(":last-child") && $this.parent("ul.sub-menu").length) {
var condition = offL > ((wW / 2) - $this.width()),
properties = {},
cssProp = {};
tooltip.stop(true).text(title);
if (condition) {
properties = {
"left": (offL - tooltip.width() - 30)
};
} else {
properties = {
"left": (offL + $this.width() + 25)
};
}
$.extend(properties, {
"top": ($this.offset().top + (posT / 2) - (tooltip.height() / 2))
});
tooltip.animate(properties, 300).fadeTo(200, 1); // SO TOOLTIP ANIMATES, BUT ONLY WHEN WINDOW WIDTH EXCEEDS 800
}
},function () {
});
} else { // IF WINDOW IS TIGHTER THAN 800 PX
// Put data back
$("li:not(.has-sub-menu) > a").each(function () {
var $this = $(this),
title = $this.data("title");
$this.attr("title", title);
});
}
}
triangleMenu();
$(window).resize(function () {
triangleMenu();
});
Опять же, я прошу прощения за обширность этого примера, но совершенно невозможно сократить его дальше, не теряя функциональность, которая не работает.
НОВИНКА: ВЕРСИЯ 2
С некоторой помощью и большим количеством тестирования и напитков с сахаром, у меня работает "главное меню". Меню измененного размера (мобильное / адаптивное) не работает.
При изменении размера на меньшее меню (вам может потребоваться изменить размер в два раза, меньше, больше, меньше), вы сможете открыть элемент, имеющий подменю, щелкнув по нему, но это не работает. При щелчке по li, подэлементы получают кучу встроенных стилей, но я понятия не имею, откуда они берутся!
overflow: hidden; display: none; height: 159px; padding-top: 0px; margin-top: -2px; padding-bottom: 0px; margin-bottom: 0px;
Я думаю, что они не показывают меню, но я не могу найти причину их.
2 ответа
База на вашем НОВОМ: ВЕРСИЯ 2
Что вам не хватает в импорте, так это то, что вы привязываете слишком много одной и той же функции щелчка к $("nav li.has-sub-menu")
при изменении размера.
Я добавляю console.log(1)
в обработчике кликов, как показано ниже:
$("nav li.has-sub-menu").click(function () {
var $this = $(this);
console.log(1);
$this.children("ul.sub-menu").stop(true).slideToggle("fast");
});
И это напечатает много 1
Я думаю, что вы не исключение.
И что более важно, количество звонящих console.log(1);
всегда даже , я действительно не знаю почему. Но это означает, что ваше подменю снова и снова показывает / скрывает, а затем, наконец, скрывает.)
Поэтому я связываю все функции щелчка перед привязкой, добавляя следующий код. Оно работает. смотрите здесь
$("nav li.has-sub-menu").unbind("click");
Тогда еще один момент, который я хочу сказать, в функции triangleMenu
, весь код будет выполняться много раз при изменении размера.
Так что я думаю, что мы можем добавить здесь логическую переменную, чтобы сохранить ее сейчас > 800
или же < 800
, поэтому мы можем выполнить весь код, только если эта переменная изменится.
И я выполняю это, как показано ниже:
var is_mobile;
function triangleMenu(){
var wW = $(window).width();
if (wW > 800 && (is_mobile === undefined || is_mobile)) {
console.log('change to pc');
is_mobile=false;
//your code here
} else if(wW <=800 && !is_mobile) {
console.log('change to mobile');
is_mobile=true;
//your code here
}
}
Вот jsfiddle.
Обновить
Есть ли у вас идеи, почему нажатие записывается более одного раза? Это так странно?
Потому что пока вы меняете размер браузера, $(window).resize
будет вызываться все время. Вы можете добавить console.log
проверить следующим образом:
$(window).resize(function () {
console.log('resizing');
triangleMenu();
});
И не могли бы вы объяснить переменную is_mobile?
Об этом вы можете сравнить код выше с вашим кодом, как показано ниже:
function triangleMenu(){
var wW = $(window).width();
if (wW > 800 ) {
console.log('change to pc');
//your code here
} else {
console.log('change to mobile');
//your code here
}
}
Это будет делать меньше console.log
, что означает, что может спасти JS от повторения одного и того же.
А также is_mobile
означает, что в то время как wW
сейчас >800
и независимо от того, какая именно ширина при изменении размера, я устанавливаю is_mobile
в false
поэтому мне не нужно делать init и bind несколько раз. Только если wW
первый <=800
Я поставил is_mobile
в true
Отметьте, что я хочу изменить размер на мобильный, затем выполните init и bind. После этого мне не нужно делать init и связывать agin, пока wW
является <=800
, Противоположность - то же самое.
Мой английский не очень хорош, я не знаю, объясню ли я это ясно.
Я не эксперт в этом вопросе, но я нашел решение вашей проблемы. После многих испытаний я обнаружил, что часть ваших функций, которые были запущены в одном из состояний if, оставалась связанной. Я обнаружил это, потому что:
$(window).resize()
вызывал функцию;- Начальный размер окна работал как ожидалось;
- Но после изменения размеров функциональность, похоже, сохранилась.
Я пришел к выводу, что существует проблема связывания, и я попробовал это, и это сработало: в заявлении else я добавил эту первую строку $("nav li").unbind('hover');
, Это избавило от функции наведения, которая оставалась привязанной к элементу.
Но потом я понял, что стрелки тоже сохраняются. Чтобы справиться с этим, мне пришлось добавить две строки кода. Сначала я добавил к утверждению else:$("ul:not(.sub-menu) > li, ul.sub-menu > li:last-child").removeClass("over-down");
,
Но этого было недостаточно, я тоже переехал $("ul:not(.sub-menu) > li, ul.sub-menu > li:last-child").not(":has(ul.sub-menu)").addClass("over-down");
в $("nav li").hover()
функция, преобразовав ее в более простую:
$(this).addClass("over-down");
,
Я не знаю, является ли это самым элегантным решением, но, похоже, оно работает. Я надеюсь, что эксперт мог бы объяснить это лучше.
Вы можете найти больше ошибок, но я думаю, что это поможет вам исправить другие проблемы с этой функцией. Возможно, изменение логики и шагов сделает код более надежным.
PS: при изменении размеров окон в Chrome все еще возникают некоторые проблемы с высотой меню.