VERSION 1. EDITED VERSION BELOW
This is a very basic representation of what I originally had, I can’t seem to get it any shorter than this, so I’m sorry for the load of code. I commented where the problem might lie.
Extended Fiddle: http://jsfiddle.net/BramVanroy/tKL8E/53/
As you can see, there is a menu that can be hovered. In normal view (horizontal menu) tooltips will appear which represent the title of the link (so basically, modified tooltips). When you resize the window to < 800, the menu should become vertical (media queries). The problem is, that the function that has been called inside the if-function, still works. The modified tooltip keeps appearing and being animating (instead of standard tooltips) and the arrows are still being positioned.
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();
});
Again, I am sorry for the extensiveness of this example, but it is quite impossible to cut it down any further, without losing the functionality that does not work.
NEW: VERSION 2
With some help and a lot of testing and sugar-overloaded drinks, I’ve got the “main menu” working. The resized (mobile/responsive) menu is not working though.
When resizing to the smaller menu (you might have to resize twice, smaller, larger, smaller), you should be able to open up an item that has a sub menu by clicking it, but this doesn’t work. When clicking a li, the sub-items gets a bunch of inline-styles but I have no idea where they come from!
overflow: hidden; display: none; height: 159px; padding-top: 0px; margin-top: -2px; padding-bottom: 0px; margin-bottom: 0px;
I think they stop the menu from showing, but I can’t seem to find the cause of them.
Base on your NEW: VERSION 2
What a import thing you are missing is that, you bind too many the same click function to
$("nav li.has-sub-menu")while resizing.I add a
console.log(1)in the click handler like below:And it will print many
1, which I think is not you excepte.And what is more important, the number of calling
console.log(1);is always even,I really don’t know why. But that means your sub-menu show/hide again and again, then finally hide.)So I unbind all click function before binding,by adding the following code. It works. see here
Then another point I want to say, in function
triangleMenu, all the code would be executed many times while resizing.So I think we may add a boolean variable here to save it is now
> 800or< 800, so we can execute all the code only if this variable change.And I perform that like below:
Here is jsfiddle.
update
Because while you resize the browser,
$(window).resizewill be called all the time.You can add a
console.logto check like the following:About this, you can compare the code above with your code before like below:
It will do less
console.log, which means can save js from doing the same thing repeatedly.And
is_mobilemeans that, whilewWis now>800and no matter how width exactly it is while resizing, I setis_mobiletofalse, so I need not to do init and bind repeatedly. Only ifwWis first<=800, I setis_mobiletotrue, mark that I now want to change to mobile size, then do init and bind. After these, I need not do init and bind agin, as long aswWis<=800. The opposite is the same.My English is not very good, I don’t know if I explain it clear.