Frage

Ich versuche, ein Navigationsmenü zu erstellen, die einige jQuery verwendet. Ich wollte Tastatur Benutzer in der Lage sein, die gleiche Erfahrung wie Maus-Nutzer haben, so dass ich die Funktionalität in meinem hover() Ereignishandler in meinen focus() und blur() Event-Handler gefunden duplizieren. Aus irgendeinem Grund, verursacht dies merkliche Verzögerung in Firefox und IE, wenn der Benutzer auf einen Link klickt, der nicht auftritt, wenn die focus() und blur() Code herausgenommen wird. Wie kann ich mich über diese zu beschleunigen? Ich habe so viel Optimierungs wie meine begrenzten JavaScript-Kenntnisse getan erlauben, aber ich habe kein „Speedup“ gesehen, also ich denke, es ist vielleicht zu in Beziehung gesetzt werden, wie dieser Browser behandelt die Ereignisse.

Gibt es etwas Haupt ich mit Blick auf? Oder gibt es alternative Möglichkeiten, die Zugänglichkeit für Tastaturbenutzer zu halten, während dieser Ereignisse nicht mit?

        var statePad=0;

            function stateChanger(ourStatePad) {
                //the purpose of this function is to translate the current state of the menu into a different graphical representation of the menu state.
                var tempVar=ouStatePad;
                var tempArray = new Array;
                tempArray[5]=0;
                for (var x=0;x < 5;x++) {
                    tempArray[x]=tempVar % 10;
                    tempVar=(tempVar-tempArray[x])/10;
                }
                for (var arrayIndex=4;arrayIndex>=0;arrayIndex--) {
                   //Calculate the proper position in our CSS sprite, based on the each link's state, as well as it's neighbors'.
                    $(".block").eq(4 - arrayIndex)
                    .css(
                        "background-position",
                        //x-position
                        ((4 - arrayIndex) * -100) + "px " + 
                        //y-position
                        (tempArray[arrayIndex] + ((3 * tempArray[(arrayIndex) + 1]) * -30))) + "px";
                }
            }


        function hoverState(index,sign) {
            var placeholder=Math.pow(10,4-index);

            if (statePad != placeholder*2)
                statePad += (placeholder * sign);
            stateChanger(statePad);
}

        .click(function() {
            var index=$("#navbar a").index(this);
            statePad=Math.pow(10,(4-index))*2;
            stateChanger(statePad);
            $(".active").removeClass("active");
            $(this).addClass("active");
        })


        .hover(
            function () {
                hoverState($("#navbar a").index(this),1);
            },
            function () {
                hoverState($("#navbar a").index(this),-1);
            });

        $("#navbar a").focus( 
            function() {
                hoverState($("#navbar a").index(this),1);
            }
        );

        $("#navbar a").blur( 
            function() {
                hoverState($("#navbar a").index(this),-1);
            }
        );  
    });

Sie können es aus hier

War es hilfreich?

Lösung 2

Ich löste dies durch vollständigen Unfall, irgendwie. Ich erkennen, dass mein Problem nicht wirklich die Verzögerung war, das war nur ein Symptom für einen „Konflikt der Ereignisse“.

Das Problem, soweit ich sagen kann ist, dass focus() ausgelöst wird entweder durch auf einen Link oder ein mousedown() auf einem Elemente Tabbing über den Fokus erhalten kann. So wird jedes Mal, wenn ein Link angeklickt, wird es Fokus zu bekommen. Aber ein click() Ereignis ist erst abgeschlossen, wenn die Maustaste losgelassen wird. So ist der Effekt, dass ich in Firefox und IE zu sehen, war ein Ergebnis einer leichten Verzögerung zwischen mousedown() und mouseup(). Ich habe versucht Auslagern nur das .click() Ereignisses in meinem Code Handhabung mousedown(), und da es nur ein einziges Ereignis, dass ich gerade aus für mich, dass in mein hoverState () Funktion integrieren entschieden. Ich landete mit diesem:

function hoverState(e) {
    var index = $(e.target.parentNode).prevAll().length;
    if (e.type == 'mousedown') {
        statePad=Math.pow(10,(4-index))*2;
        $(".active").removeClass('active');
        $("#"+ e.target.id).addClass('active');
}
else {
   var sign = (e.type === 'mouseenter' || 
                 e.type === 'focus')? 1 : -1;
 var placeholder=Math.pow(10,4-index);
    if (statePad != placeholder*2)
        statePad += (placeholder * sign);
 $('h1').text(statePad + " " + e.type);
    }
    stateChanger(statePad);
}

$("#navbar a").bind("mouseenter mouseleave focus blur mousedown", hoverState);

Allerdings verursacht dies einige bizarre Verhalten, das die statePad Variable vermasselt. Ich kehrte zurück zu dem Code, den Russ Cam mir zur Verfügung gestellt, und begann, Dinge zu überdenken. Ich versuchte es in Opera heraus, die ich noch nicht getan hatte, und es funktionierte gut. Ich habe versucht, es in Safari und Chrome, und sie arbeiteten wie gewohnt gut. Ich habe versucht, es in Firefox, nur auf einen Griff zu bekommen versucht, was macht es anders, und ... es funktioniert!

Ich sah meinen Code zurück, und es stellt sich heraus, dass ich immer noch die hoverState Funktion zum mousedown() Ereignis wurde verbindlich. Ich bin mir nicht ganz sicher, warum dies funktioniert, aber es funktioniert. Es behebt das Problem in IE, wie gut. Strangle, verursacht es ein neues Problem in Chrome, es so gering ist, dass ich nicht einmal über das Gehen zu sorgen.

Ich glaube nicht, dass ich in der Lage wäre diese Hilfe ohne Russ zu lösen, so mag ich ihn für all seine Hilfe in dieser noch einmal danken.

Andere Tipps

Es gibt eine Menge unnötiger Verlängerung rel="nofollow der Umfang Kette in Ihrem Code und eine längere Umfang Kette wird länger dauern, zu lösen. Es könnte auf die folgenden verkürzt werden

$("navbar a").click(blah) 
             .hover(foo,bar)
             .focus(foo)
             .blur(bar);

Hoffentlich in weniger eine merkliche Verzögerung zur Folge haben sollte. Wenn Sie noch merkliche Verzögerung sehen nach dieser Änderung, bitte den Code für die Event-Handler-Funktionen schreiben, da es Verbesserungen sein, die auch an diesen Code gemacht werden können.

EDIT:

Als Antwort auf Ihren Kommentar, können Sie den Index in der Funktion erhalten die in event Eigenschaft target Objekts bestanden mit, die das Element sein wird, dass das Ereignis wurde am angehoben. Also, um den Index eines <a> Element in allen <a> Elemente in der <ul> mit id navbar , können wir die Tatsache nutzen, dass jede <a> innerhalb eines <li> enthalten ist, also der Index in jedem Fall gleich sein. Mit diesem Geist ist, wird event.target das <a> Element, dass das Click-Ereignis auf angehoben wird, wird event.target.parentNode das Element der <a> Eltern sein, die die <li> ist

den Index erhalten, könnten Sie

function hoverState(e) { 
    // get the index of the <a> element, which will be the same
    // as the index of the <li> that contains it in the <ul>
    //
    var index = $(e.target.parentNode).prevAll().length; 
    //
    // get the sign
    var sign = (e.type === 'mouseenter' || e.type === 'focus')? 1 : -1;
} 

Dies wird die Notwendigkeit für anonyme Funktion Event-Handler Einwickeln hoverState entfernen.

Hier ist ein überarbeitetes Code

var statePad=0;

// the purpose of this function is to translate 
// the current state of the menu into a different 
// graphical representation of the menu state.
//
function stateChanger(ourStatePad) {

    var tempVar=ourStatePad;
    var tempArray = [0,0,0,0,0];
    for (var x=0;x < 5;x++) {
        tempArray[x]=tempVar % 10;
        tempVar=(tempVar-tempArray[x])/10;
    }
    // Calculate the proper position in our CSS sprite, 
    // based on the each link's state, as well as it's neighbors'
    //
    var arrayIndex=4;
    while (arrayIndex--) {

        $("#rightpostheader div.block").eq(4 - arrayIndex)
            .css(
                "backgroundPosition",
                //x-position
                ((4 - arrayIndex) * -100) + "px " + 
                //y-position
                (tempArray[arrayIndex] + ((3 * tempArray[(arrayIndex) + 1]) * -30))) + "px";
    }

}


function hoverState(e) {
    var index = $(e.target.parentNode).prevAll().length;
    var sign = (e.type === 'mouseenter' || 
                e.type === 'focus')? 1 : -1;
    var placeholder=Math.pow(10,4-index);

    if (statePad != placeholder*2)
        statePad += (placeholder * sign);
    stateChanger(statePad);
}

$("#navbar a")
    .click(function(e) {
        // might be able to rework this into using hoverState too
        var $this = $(e.target);

        // get the index of the parent <li>
        var index= $this.parent().prevAll().length;

        statePad=Math.pow(10,(4-index))*2;

        stateChanger(statePad);

        $("#navbar a").removeClass('active');
        $this.addClass('active');
    })
    .bind("mouseenter mouseleave focus blur", hoverState);  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top