Damit das funktioniert, müssen Sie ein paar Schritte unternehmen.
Erstellen Sie zunächst die übergeordneten Hover-Funktionen, die da wären enter()
y exit()
. Diese werden mit der Funktion hover()
Funktion. Erstellen Sie dann die Kinder enterChild()
y exitChild()
Funktion. Die Kinder ändern lediglich eine Markierung, an der Sie erkennen können, ob ein Kind mit dem Mauszeiger bewegt wird und somit das Elternteil immer noch als mit dem Mauszeiger bewegt betrachtet wird.
Was auch immer Sie in der Zukunft tun wollen exit()
können Sie dies nicht sofort tun, da die Ereignisse in der richtig Reihenfolge für eine grafische Benutzeroberfläche, aber die falsche Reihenfolge für diesen speziellen Fall:
enter parent
exit parent
enter child
exit child
enter parent
exit parent
Wenn also Ihr exit()
Funktion aufgerufen wird, kann es sein, dass Sie das Kind gleich danach eingeben, und wenn Sie etwas verarbeiten wollen, wenn beide das Elternteil und das Kind verlassen werden, nur auf die exit()
wird sicherlich falsch sein. Beachten Sie, dass der Browser so geschrieben ist, dass ein Exit-Ereignis immer eintritt, wenn ein Enter-Ereignis stattgefunden hat. Die einzige Ausnahme kann sein, wenn Sie die Registerkarte/das Fenster schließen, in diesem Fall können sie auf das Senden weiterer Ereignisse verzichten.
In der übergeordneten exit()
Funktion verwenden wir eine setTimeout()
aufrufen, um einen asynchronen Aufruf zu tätigen, der nach dem enter()
Funktion eines Kindes geschieht. Das heißt, wir können dort ein Flag setzen und es in der asynchronen Funktion testen.
MyNamespace = {};
MyNamespace.MyObject = function()
{
var that = this;
// setup parent
jQuery(".parentDiv").hover(
function()
{
that.enter_();
},
function()
{
that.exit_();
});
// setup children
jQuery(".parentDiv .children").hover(
function()
{
that.enterChild_();
},
function()
{
that.exitChild_();
});
}
// couple variable members
MyNamespace.MyObject.prototype.parentEntered_ = false;
MyNamespace.MyObject.prototype.inChild_ = false;
MyNamespace.MyObject.prototype.enter_ = function()
{
// WARNING: if the user goes really fast, this event may not
// happen, in that case the childEnter_() calls us
// so we use a flag to make sure we enter only once
if(!this.parentEntered_)
{
this.parentEntered_ = true;
... do what you want to do when entering (parent) ...
}
};
// NO PROTOTYPE, this is a static function (no 'this' either)
MyNamespace.MyObject.realExit_ = function(that) // static
{
if(!that.inChild_)
{
... do what you want to do when exiting (parent) ...
that.parentEntered_ = false;
}
};
MyNamespace.MyObject.prototype.exit_ = function()
{
// need a timeout because otherwise the enter of a child
// does not have the time to change inChild_ as expected
setTimeout(MyNamespace.MyObject.realExit_(this), 0);
};
// detect when a child is entered
MyNamespace.MyObject.prototype.enterChild_ = function()
{
this.inChild_ = true;
this.enter_(); // in case child may be entered directly
};
// detect when a child is exited
MyNamespace.MyObject.prototype.exitChild_ = function()
{
this.inChild_ = false;
// We cannot really do this, although in case the child
// is "exited directly" you will never get the call to
// the 'exit_()' function; I'll leave as an exercise for
// you in case you want it (i.e. use another setTimeout()
// but save the ID and clearTimeout() if exit_() is not
// necessary...)
//this.exit_()
};