2012-05-08 15 views
5

OTWÓRZ DO DYSKUSJI Szukam optymalizacji tego kodu, ewentualnie zrobić obiekt. Ale co ważniejsze, jestem nowy z funkcjami. Chciałbym nauczyć się przekazywać, pobierać, zwracać zmienne. Jeśli ktoś ma jakieś dobre linki do tutorialu lub chciałby o tym porozmawiać, proszę zacznij tutaj. :)Używanie Alpha z PNG jako "hotspot" do dołączania zdarzenia click/hover, możliwe?

Jak wiemy, obrazy są prostokątami. Mam kilka przezroczystych plików PNG wewnątrz div na oddzielnych warstwach z-index. Dotarłem do problemu, w którym próbowałem kliknąć jedno z obrazów, ale było blokowane przez div na nim z wyższym indeksem Z. Czy możliwe jest kliknięcie poprzez PNG i ich div rodziców, aby osiągnąć ten efekt? Proszę zobaczyć załączony obraz jako odniesienie, lepiej ilustruje mój punkt widzenia.

Dzięki!

img

W skrócie, z jakiegoś powodu, że mogę używać alfa PNG jako hitspot. LOL @ ten pomysł. Stworzyłem więc nakładki div w nowym, oddzielnym pojemniku, który działał jako miejsce docelowe.

img2

Jak widać jest to nieskończony karuzela. Indeksy z hitspotów, a także z-indeksy obrazów zmieniają się po kliknięciu. To był interesujący projekt, co najmniej. Chciałabym go zoptymalizować i nauczyć się, jak być bardziej efektywnym z funkcjami (np. Przekazywanie, odzyskiwanie varów, zwracanie varów itp.).

Będę umieszczać javascript, kiedy wrócę do domu, by zainicjować interesującą rozmowę, mam nadzieję . Jeśli masz pomysły na optymalizację, udostępnij je! :)

(function (w, d) { 
$(w).load(function() { //window load 
    preload(); 
    $('#info div a:not([rel=ad])').find('img').hide(); //hides 'learn more' buttons 
}); //end window.load 

$(d).ready(function() {  //document ready 
    onHover();     //activate hover 
    onClick();     //activates click function 
});        //end document.ready 

var isFirst = ["1"],  //flag to see if the first click was triggered on a hotspot or not 
    pxPos = ["1px", "399px", "577px", "782px", "969px", "1162px", "1330px"], //pixel position where we will animate the targets 
    name = ["bill", "sophia", "brian", "jenn", "mom"],       //names of talent; array used 
    thisZ = 0;                 //z-index used later to swap current target to front, and move others behind current 

$('.left, .right').hide(); 

function onHover() {    //hover function -- note: 'thisName' is a different variable in this f(n) than in onClick() 
    $('.hit').hover(function() { 
     var _this = this, 
     thisName = $(_this).parent().attr('id'), 
     img = '_img/' + thisName + '.png'; 
     $(_this).parent().next().find('img').attr('src', img); 

    }, function() { 
     var _this = this, 
     thisName = $(_this).parent().attr('id'), 
     img = '_img/' + thisName + '-d.png'; 
     if (!($(this).parent().next().hasClass('current'))) { 
      $(_this).parent().next().find('img').attr('src', img); 
     } 
    }) 
} 

function onClick() { 
    $('a.left').bind('click', function (e) { 
     e.preventDefault(); 
     //left arrow click function 
     if (!$('.p').is(":animated")) {      //checks if animation is running and prevents click action 
      pos = 'p5'; 
      var o = [name[1],name[2],name[3],name[4],name[0]]; 
      name = o; 
      var thisName = name[3]; 
      updateArr(thisName, pos); 
     }; //end if animated 
    }) 

    $('a.right').bind('click', function (e) {    //right arrow click function 
     e.preventDefault(); 
     if (!$('.p').is(":animated")) {      //checks if animation is running and prevents click action 
      pos = 'p3'; 
      var o = [name[4],name[0],name[1],name[2],name[3]]; 
      name = o; 
      var thisName = name[3]; 
      updateArr(thisName, pos); 
     } //end if animated 
    }) 

    $('.hit').bind('click', function() {     //click function 
     if (!$('.p').is(":animated")) {      //checks if animation is running and prevents click action 
      var _this = this; 
      var thisName = $(_this).parent().attr('id'); //name of person who is clicked on 

      if(isFirst[0] === "1") {      //execute actions on first click 
       $('h1').hide(); 
       $('.left, .right').fadeIn().show();   //fade in arrows 
       $('#bg2').fadeIn().show();     //fade in dark bg 

       var pos = checkPosition(_this);    //checks position of clicked person 
       updateArr(thisName, pos);     //update array 

       isFirst[0] = "2";       //sets flag to "not first click" 

      }else if(isFirst[0] === "2") {     //all other clicks but the first click 

       var pos = checkPosition(_this);    //checks position of clicked person 
       updateArr(thisName, pos);     //update array 

      } //end if 
     } //end if animated 
    })  //end hit check 
} 


function checkPosition (_this, thisName) { //find current position and return 
    var pos; 
    if($(_this).parent().next().hasClass('p1')) { 
     pos = 'p1'; 
    }else if($(_this).parent().next().hasClass('p2')) { 
     pos = 'p2'; 
    }else if($(_this).parent().next().hasClass('p3')) { 
     pos = 'p3'; 
    }else if($(_this).parent().next().hasClass('p4')) { 
     pos = 'p4'; 
    }else if($(_this).parent().next().hasClass('p5')) { 
     pos = 'p5'; 
    } 
    return pos; 
} //end checkClickPosition() 

function updateArr (thisName, pos) { //update array 

    // find person index in array 
    for(l=0; l <= name.length; l++) { 
     if(thisName == name[l]) { 
      var thisIndex = l; 
     } 
    } //end for 

    // search for index by matching index to position in array. create new array. 
    if(thisName === name[thisIndex]) { 
     var o = []; 

     if(thisIndex === 0) { 
      o = [name[2],name[3],name[4],name[0],name[1]]; 
     }else if(thisIndex === 1) { 
      o = [name[3],name[4],name[0],name[1],name[2]]; 
     }else if(thisIndex === 2) { 
      o = [name[4],name[0],name[1],name[2],name[3]]; 
     }else if(thisIndex === 3) { 
      o = [name[0],name[1],name[2],name[3],name[4]]; 
     }else if(thisIndex === 4) { 
      o = [name[1],name[2],name[3],name[4],name[0]]; 
     } 
     name = o; //update array with new array 

     updateFlags(); //update current flag 

    } //end if 

    //removes previous hilight and current class 
    $.each($('.p'), function() { 
     if(($(this).attr('class').length > 5)) { 
      var oldImg = $(this).find('img').attr('src'); 
      img = '_img/' + $(this).prev().attr('id') + '-d.png'; 
      $(this).find('img').attr('src', img); 
      $(this).removeClass('current'); 
     } 
    }); 

    //creates new hilight 
    $('#' + thisName).next().addClass('current'); 
    img = '_img/' + thisName + '.png'; 
    $('#' + thisName).next().find('img').attr('src', img); 

    updateZIndex();   //update z-indexes 
    animate(pos);   //animates array 

    var current = thisName; 
    return disorderText(current); 

} //end updateArr() 

function updateFlags() { 
    //removes position flags 
    $('.p').each (function() { 
     $(this).removeClass('p1 p2 p3 p4 p5'); 
    }); //end each 

    //add new flags 
    for(i=0; i < name.length; i++) { 
     $('#' + name[i]).next().addClass('p' + (i + 1)); 
    } //end for 
} //end updateFlags() 

function updateZIndex (thisZ) { 
    //re-orders hotspot z-indexes 
    $("#" + name[3]).children().each(function(thisZ) { 
     thisZ++; 
     $(this).css({'z-index': thisZ + 800}); 
    }); 
    $("#" + name[4]).children().each(function(thisZ) { 
     thisZ++; 
     thisZ = thisZ + 1; 
     $(this).css({'z-index': thisZ + 700}); 
    }); 
    $("#" + name[2]).children().each(function(thisZ) { 
     thisZ++; 
     thisZ = thisZ + 1; 
     $(this).css({'z-index': thisZ + 600}); 
    }); 
    $("#" + name[1]).children().each(function(thisZ) { 
     thisZ++; 
     thisZ = thisZ + 1; 
     $(this).css({'z-index': thisZ + 500}); 
    }); 
    $("#" + name[0]).children().each(function(thisZ) { 
     thisZ++; 
     thisZ = thisZ + 1; 
     $(this).css({'z-index': thisZ + 400}); 
    }); 
    $('.p1').css({'z-index': 40}); 
    $('.p2').css({'z-index': 50}); 
    $('.p3').css({'z-index': 60}); 
    $('.p4').css({'z-index': 70}); 
    $('.p5').css({'z-index': 30}); 

} //end updateZIndex() 

function animate (pos) { 

    //set up selector names for hitspot container and image container 
    var selector1 = '#' + name[0] + ', #' + name[0] + 'i', 
     selector2 = '#' + name[1] + ', #' + name[1] + 'i', 
     selector3 = '#' + name[2] + ', #' + name[2] + 'i', 
     selector4 = '#' + name[3] + ', #' + name[3] + 'i', 
     selector5 = '#' + name[4] + ', #' + name[4] + 'i', 
     easeType = 'easeOutCubic', 
     easeOutType = 'easeOutCubic'; 

    if (pos === 'p1') { 
     $(selector1).animate({'left': pxPos[6]}, 400, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[0]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[1]}, 600, easeType); //p5 
     $(selector2).animate({'left': pxPos[6]}, 400, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[0]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[2]}, 600, easeType); //p1 
     $(selector3).animate({'left': pxPos[6]}, 400, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[0]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[3]}, 600, easeType); //p2 
     $(selector4).animate({'left': pxPos[4]}, 1350, easeType); //p3 
     $(selector5).animate({'left': pxPos[5]}, 1350, easeType); //p4 
    }else if (pos === 'p2') { 
     $(selector1).animate({'left': pxPos[6]}, 400, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[0]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[1]}, 700, easeType); //p5 
     $(selector2).animate({'left': pxPos[6]}, 400, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[0]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[2]}, 700, easeType); //p1 
     $(selector3).animate({'left': pxPos[6]}, 400, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[0]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[3]}, 700, easeType); //p2 
     $(selector4).animate({'left': pxPos[4]}, 1550, easeType); //p3 
     $(selector5).animate({'left': pxPos[5]}, 1550, easeType); //p4 
    }else if (pos === 'p3') { 
     $(selector1).animate({'left': pxPos[6]}, 200, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[0]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[1]}, 500, easeType); //p5 
     $(selector2).animate({'left': pxPos[2]}, 700, easeType); //p1 
     $(selector3).animate({'left': pxPos[3]}, 700, easeType); //p2 
     $(selector4).animate({'left': pxPos[4]}, 700, easeType); //p3 
     $(selector5).animate({'left': pxPos[5]}, 700, easeType); //p4 
    }else if (pos === 'p4') { 
     $(selector1).animate({'left': pxPos[1]}, 500, easeType); //p5 
     $(selector2).animate({'left': pxPos[2]}, 700, easeType); //p1 
     $(selector3).animate({'left': pxPos[3]}, 700, easeType); //p2 
     $(selector4).animate({'left': pxPos[4]}, 700, easeType); //p3 
     $(selector5).animate({'left': pxPos[5]}, 700, easeType); //p4 
    }else if (pos === 'p5') { 
     $(selector1).animate({'left': pxPos[1]}, 700, easeType); //p5 
     $(selector2).animate({'left': pxPos[2]}, 700, easeType); //p1 
     $(selector3).animate({'left': pxPos[3]}, 700, easeType); //p2 
     $(selector4).animate({'left': pxPos[4]}, 700, easeType); //p3 
     $(selector5).animate({'left': pxPos[0]}, 200, easeOutType).delay(0).animate({'opacity': 0}, 0).animate({'left':pxPos[6]}, 0).animate({'opacity': 100}, 0).animate({'left': pxPos[5]}, 500, easeType); //p4 
    } 

} //end animate() 

function disorderText (current) { 

    var _this   =  ['swd', 'osa', 'nar'], 
     swd    =  "Of the 15 million Americans who work evening or night shirts, 25% may have shift work disorder.", 
     osa    =  "18 million Americans suffer from OSA.", 
     nar    =  "Narcolepsy affects 1 in every 2,000 Americans.", 
     link   =  "<a href=''><img src='_img/learn-more.png' width='125' height='31' class='learn_more' /></a>", 
     brian_quote  =  '"' + "I get enough sleep during the day, but I'm still exhausted at work." + '"', 
     sophia_quote =  '"' + "Since I started working nights, I struggle to stay awake." + '"', 
     jenn_quote  =  '"' + "I'm so tired on my shift that it's hard to do my job" + '"', 
     bill_quote  =  '"' + "I struggle to stay awake even outside of work - I'm almost dozing off at my son's Little League games." + '"', 
     mom_quote  =  '"' + "Quote to come." + '"', 
     i    =  0, 
     p_name   =  "", 
     quote   =  "", 
     info   =  "", 
     disorderArr  =  ["_this", "swd", "osa", "nar", "link", "brian_quote", "sophia_quote", "jenn_quote", "bill_quote", "mom_quote", "i", "pname"]; 


    $('#info').children().each (function() { 
     $(this).removeClass('open'); 
     $(this).find('.content').html('<p>'); 
    }); 

    switch(current) { 
     case 'brian' : i = 0; 
          p_name = '<h2><b>Alex,</b> Bartender</h2>'; 
          info = swd; 
          quote = brian_quote; 
          break; 
     case 'sophia' : i = 0; 
          p_name = '<h2><b>Sophia,</b> EMT</h2>'; 
          info = swd; 
          quote = sophia_quote; 
          break; 
     case 'jenn'  : i = 0; 
          p_name = '<h2><b>Susan,</b> Nurse</h2>'; 
          info = swd; 
          quote = jenn_quote; 
          break; 
     case 'bill'  : i = 1; 
          p_name = '<h2><b>Martin,</b> Real Estate</h2>'; 
          info = osa; 
          quote = bill_quote; 
          break; 
     case 'mom'  : i = 2; 
          p_name = '<h2><b>Susan,</b> Mom</h2>'; 
          info = nar; 
          quote = mom_quote; 
          break; 
    } 
    $('#' + _this[i]).addClass('open'); 

    //handles information swap 
    $('#info').children().each (function() { 
     if($(this).hasClass('open')) { 
      $(this).find('.header span').addClass('down'); 
      $(this).children().find('a img').show();   //show 'learn more' button 
      $(this).find('.content').addClass('disorder'); 
     }else if(!$(this).hasClass('open')) { 
      //$(this).children().find('a').hide();    //hide 'learn more' button 
      $(this).find('.header span').removeClass('down'); 
      $(this).find('.content').removeClass('disorder'); 
     } 
    }); //end show/hide 'learn more' button 

    return $('#' + _this[i]).find('.content').html(p_name + '<p class="gen_quote"><i>' + quote + '</i></p>' + '<p class="gen_info"><b>' + info + '</b></p>' + '<p class="learn-more">' + '&nbsp' + link); 
} 

function preload(imgArray) { 
    $(imgArray).each(function(){ 
     $('<img/>')[0].src = this; 
    }); 
} 

preload([ '_img/ad.png', '_img/arrow_sm_d.png', '_img/arrow_sm.png', '_img/arrow-left.png', '_img/arrow-right.png', '_img/bill-d.png', '_img/bill.png', '_img/border.png', '_img/brian-d.png', '_img/brian.png', '_img/corner.png', '_img/hit.gif', '_img/jenn-d.png', '_img/jenn.png', '_img/mom-d.png', '_img/mom.png', '_img/sidebar-bg.png', '_img/sophia-d.png', '_img/sophia.png', '_img/stone-bg-d.jpg', '_img/stone-bg.jpg' ]); 

} (okno, dokument));

+3

pan zapomniał załączony obraz, który ilustruje sytuację. – Peter

+0

Czy rozwiązałeś swój problem? – Peter

+0

Mój problem nie został rozwiązany za pomocą sugestii "wskaźników-zdarzeń". Ale rozwiązałem mój problem. Problem polegał na tym, że musiałem utworzyć nakładki div, aby działały jako "hotspoty", a ja użyłem jQuery do wykrywania zawisu w tych miejscach, aby zamienić obraz za nim. – levelafter

Odpowiedz

0

To świetne pytanie i zazwyczaj nie jestem pesymistą, ale naprawdę nie sądzę, że znajdziesz tu rozwiązanie, które nie wymaga zmiany gry. To znaczy, sugerowałbym użycie SVG zamiast PNG. W ten sposób możesz mieć punkty aktywne, które pasują do granic Twojego kształtu. Nie jestem pewien, czy to zadziała w twoim scenariuszu. Zobacz bibliotekę Raphaël-JavaScript.

Wiesz co? Możesz również użyć elementu Canvas HTML5 do narysowania obrazu rastrowego na płótnie, ale prawdopodobnie nadal będziesz musiał ręcznie przejść przez każdy piksel, aby skonstruować na nim hotspot, wykorzystując kanał alfa jako dane.

Żałuję, że nie mamy takiej możliwości, rodzimy, ale tak naprawdę nie sądzę. Mam nadzieję, że dałem dobre alternatywy.

+0

Świetny wgląd sjfedi! Uwielbiam, gdy ktoś wprowadza nową perspektywę. Na pewno będę o tym pamiętał przy przyszłych projektach, a także będę je ulepszał w swoim własnym czasie, tylko po to, żeby się czegoś nauczyć! :) – levelafter

1

spróbować pointer-events własności CSS:

właściwości CSS-events wskaźnik pozwala autorom kontrolować, w jakich okolicznościach (jeśli występują) dany element graficzny może stać się celem zdarzenia myszy. Gdy ta właściwość jest nieokreślona, ​​do treści SVG mają zastosowanie te same cechy wartości visiblePainted.

Oprócz wskazania, że ​​element nie jest celem zdarzeń myszy, wartość none instruuje zdarzenie myszy, aby przejść "przez" element i wycelować to, co jest "pod" tym elementem.

https://developer.mozilla.org/en/CSS/pointer-events

+0

"Pointer-events" wydają się bardzo ciekawe, ale niestety wciąż jest to "eksperymentalne" i potrzebuję tego do pracy w 100% dla dużego klienta. będę to badać dalej. dziękuję za napiwek !! – levelafter

0

Interesującym podejściem byłoby za pomocą właściwości CSS pointer-events:none, to wyłącza element z otrzymywania jakiegokolwiek zdarzenia najechania kursorem i kliknij. Zamiast tego przekaże go do elementu poniżej.

Możesz sprawdzić ten ekstremalnie useful discussion, aby uzyskać dodatkowe informacje na ten temat.

Ponadto należy pamiętać o zgodności tej właściwości CSS z przeglądarką. Prawdopodobnie będziesz musiał trochę zbadać, aby uzyskać ostateczne odpowiedzi na pytanie, jak to jest zgodne i jakie wersje.

Oto moja krótka badania:

Pointer-Events Compatibility from Mozilla Dev Network

Pointer-Events Compatibility from 'Can I Use?'

Pointer-Events Tutorial and Some Compatibility Notes

Powiązane problemy