문제

jQuery를 사용하는 탐색 메뉴를 만들려고합니다. 키보드 사용자가 마우스 사용자와 동일한 경험을 할 수 있기를 원했기 때문에 내에서 발견 된 기능을 복제하고 싶습니다. hover() 내 이벤트 핸들러 focus() 그리고 blur() 이벤트 처리기. 어떤 이유로, 이것은 사용자가 링크를 클릭 할 때 Firefox에서 눈에 띄는 지연이 발생합니다. focus() 그리고 blur() 코드가 꺼졌습니다. 이걸 속도를 높이는 방법은 무엇입니까? 제한된 JavaScript 지식이 허용되는만큼 최적화했지만 "속도 업"을 보지 못했기 때문에 이러한 브라우저가 이벤트를 처리하는 방식과 관련이있을 수 있다고 생각합니다.

내가 간과하고있는 중요한 것이 있습니까? 아니면 이러한 이벤트를 사용하지 않고 키보드 사용자의 접근성을 유지하는 대안적인 방법이 있습니까?

        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);
            }
        );  
    });

당신은 그것을 확인할 수 있습니다 여기

도움이 되었습니까?

해결책 2

나는 이것을 완전히 사고로 해결했다. 나는 내 문제가 실제로 지연이 아니라는 것을 깨달았습니다. 그것은 단지 "사건의 충돌"의 증상 일뿐입니다.

내가 알 수있는 한 문제는 focus() 링크 또는 mousedown() 초점을 맞을 수있는 요소에. 따라서 링크를 클릭 할 때마다 집중하고 있습니다. 그러나, a click() 마우스가 해제 될 때까지 이벤트가 완료되지 않습니다. 그래서 Firefox와 IE에서 내가 보았던 효과는 약간의 지연의 결과였습니다. mousedown() 그리고 mouseup(). 나는 단지 교환을 시도했다 .click() 내 코드에서 이벤트 처리 mousedown(), 그리고 그것은 단 하나의 이벤트 일 뿐이므로 이벤트를 HoverState () 함수에 통합하기로 결정했습니다. 나는 이것으로 끝났다 :

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);

그러나 이로 인해 StatePad 변수를 망쳐 놓은 기괴한 동작이 발생했습니다. 나는 Russ Cam이 나에게 제공 한 코드로 되돌아 가서 물건을 다시 생각하기 시작했습니다. 나는 아직하지 않은 Opera에서 그것을 시도했지만 잘 작동했습니다. 나는 Safari와 Chrome에서 그것을 시도했고 평소처럼 잘 작동했습니다. 나는 Firefox에서 그것을 시도했는데 단지 그것을 다르게 만드는 것을 다루려고 노력했고 ... 작동하고 있었다!

나는 내 코드를 되돌아 보았고, 여전히 호버 스테이트 기능을 mousedown() 이벤트. 이것이 왜 작동하는지 잘 모르겠지만 그렇게합니다. IE의 문제도 해결됩니다. 교살, 그것은 크롬에서 새로운 문제를 일으킨다. 너무 사라해서 걱정조차하지 않을 것이다.

나는 Russ의 도움없이 이것을 해결할 수 있었을 것이라고 생각하지 않으므로, 나는 이것에 대한 그의 모든 도움에 대해 다시 감사하고 싶습니다.

다른 팁

불필요한 것이 많이 있습니다 스코프 체인의 연장 코드에서는 더 긴 스코프 체인이 해결하는 데 시간이 더 걸립니다. 다음으로 단축 될 수 있습니다

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

바라건대 이것은 눈에 띄는 지연이 줄어들어 야합니다. 이 변경 후에도 여전히 눈에 띄는 지연이 보이면 해당 코드에 대한 개선이있을 수 있으므로 이벤트 핸들러 기능 코드를 게시하십시오.

편집하다:

의견에 응답하여 전달 된 내용을 사용하여 함수의 색인을 얻을 수 있습니다. event 사물 target 재산은 이벤트가 제기 된 요소가 될 것입니다. 따라서 인덱스를 얻으려면 <a> 모든 요소 <a> 요소의 요소 <ul> ID와 함께 NAVBAR, 우리는 각각의 사실을 사용할 수 있습니다 <a> a <li>, 따라서 각 경우의 색인이 동일합니다. 이것으로 마음이 있습니다. event.target 할 것입니다 <a> 클릭 이벤트가 제기 된 요소, event.target.parentNode 부모의 요소가 될 것입니다 <a> 그것이 <li>

색인을 얻으려면 사용할 수 있습니다

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;
} 

이렇게하면 익명 기능 이벤트 핸들러가 호버 스테이트를 포장 할 필요가 없습니다.

재 작업 된 코드는 다음과 같습니다

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);  
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top