Reputation: 437
I'm very new to javascript and I'm trying to give some dynamic features to a site I'm working on. In particular, I want to have an unfolding menu item that unfolds and folds back whenever the mouse is on and off of it, respectively.
I got the unfolding part down but the event listener that triggers the folding back does it whenever the mouse if off of the area where the menu item used to be, event though it's just been extended.
The HTML markup looks like this:
<nav id="nav">
<ul>
<li id="elemPlaces"><ul id="drop"><li>Places</li></ul></li>
</ul>
</nav>
The event listeners are declared like this:
<script type="text/javascript">
var extended = false;
var listPlace = (<?php echo json_encode($list_place); ?>);
document.getElementById("elemPlaces").addEventListener("mouseover", extend);
document.getElementById("elemPlaces").addEventListener("mouseout", retract);
</script>
and the extend and retract functions are the following:
function extend()
{
if(!extended)
{
var drop = document.getElementById("drop");
var form = document.createElement("form");
form.setAttribute("action", "place.php");
form.setAttribute("method", "get");
drop.appendChild(form);
for(var i = 0; i < listPlace.length; i++)
{
var li = document.createElement("li");
var input = document.createElement("input");
li.setAttribute("class", "dropOption");
input.setAttribute("type", "submit");
input.setAttribute("name", "location");
input.setAttribute("value", listPlace[i]);
li.appendChild(input);
form.appendChild(li);
}
extended = true;
}
}
function retract()
{
var dropOption = document.getElementsByClassName("dropOption");
while(dropOption[0])
{
dropOption[0].parentNode.removeChild(dropOption[0]);
}
extended = false;
}
I realize it all must look amateurish but like I said, I'm new to this. I'd really appreciate it if someone could help me.
Upvotes: 0
Views: 79
Reputation: 13949
Okay JSFiddle seems to be down, so here is a Plunker
Basically :
mouseenter
and mouseleave
(see this question)<a href="yourpage.php?yourOption=yourValue">
. It is simpler. You don't need forms for this.$list_place
comes from an AJAX asynchronous request, then obviously you can't do anything else but modify the DOM dynamically. However if you know beforehand what the content of your list will be, best it to just write everything to the HTML, and add classes like class="unexpanded/expanded"
, and have a CSS .unexpanded{display: none}
. Then you just need to toggle/change the classUpvotes: 1
Reputation: 13949
So basically what you want to so, is make sure the menu stays unfolded a certain amount of time before folding back ? Here are some ideas
Instead of calling retract
on mouseout
, you could call another function with a timeout, like retract_after
function retract_after(){
setTimeout(function(){ retract() }, 3000);
}
But this could lead to weird situations (imagine the user moves the mouse on the menu just after moving it out, before the timeout expired...). So you might want to lookup how to empty the queue or remove EventListeners.
Or, what you could do, is only attach the "retract" eventListener at the end of the mouseover function (and also eventually with a timeout), and remove the eventlistener while or after it is retracting.
Also the animate() function of jquery library already somewhat produces by default the behavior you're looking (it queues animation, but if a user quickly triggers mouseenter and mouseout event listeners, the menu will keep folding/unfolding till it empties the queue)
Upvotes: 0