2016-11-07 2 views
1

Ich habe eine Frage, die als eine praktische begann, wie ich ein Element mit einem Video einklappen möchte, wenn das Video endet, für die ich einen Event-Listener hinzufügen muss, aber Da es nicht funktionierte, begann ich ein paar Tests durchzuführen und ich verstehe nicht, wie JavaScript auf Variablen zugreift.Variabler Bereich in Javascript - nicht vom Ereignis-Listener abgeholt

Ok, also in meinem Projekt habe ich ein Video in einem Iframe, etwa so:

html

<p> ...some tex... 
<span id="clickable" class="link">click me to watch video</span>.<span><iframe id="frame" class="rect" src="iframe.html" scrolling="no" marginwidth=0 marginheight=0></iframe></span> 
...some more tex...</p> 

die iframe hat gerade ein Video

iframe:

<!DOCTYPE html> 
<html> 
<head> 
    <title></title> 
    <script type="text/javascript" src="jquery.js"></script> 
    <script type="text/javascript" src="script2.js"></script> 
    <link rel="stylesheet" type="text/css" href="styles.css"> 
</head> 
<body> 
    <video id="myVid" width="350" height="200" > 
     <source src="someVideo.mp4" type="video/mp4"> 
    </video> 
</body> 
</html> 

das JavaScript ist wie folgt:

$(document).ready(function(){ 


    $("#clickable").click(function(){ 

     var rect = $(this).next().find('.rect'); 

     if (rect.hasClass("open")){ 

      rect.removeClass("open"); 

      rect.contents().find("#myVid").get(0).pause(); 

     } else { 

     rect.addClass("open"); 

     rect.contents().find("#myVid").get(0).play(); 
     } 
    }); 

und die CSS

.rect{ 
    float: left; 
    height: 0px; 
    width: 350px; 
    display: block; 
    margin: 0px; 
    padding: 0px; 
    opacity: 0; 

    transition-property: all; 
    transition-duration: 2s; 
    transition-timing-function: ease-in-out; 
} 

.open { 
    height: 200px; 
    width: 350px; 
    opacity: 1; 
    padding-bottom: 10px; 
    padding-top: 10px; 
} 

Ok, so das funktioniert. Wenn ich auf den Link "klickbar" klicke, fügt das Javascript dem iframe die Klasse "open" hinzu, wodurch die Höhe von 0 auf 200px steigt und die Video Slides geöffnet werden. Wenn ich dann erneut klicke, wird das Video geschlossen. Also, was ich versuche zu tun, um eine Funktion hinzuzufügen, die auch das Video schließen wären, wenn das Video mit dieser Funktion endet:

$('#myVid').on('ended',function(){ 
     rect.removeClass("open"); 
     alert('finished'); 
    }); 

Und hier ist, wenn das Problem beginnt. Die Frage ist, wo diese Funktion platziert werden soll. Wenn ich es außerhalb der Funktion "klickbar" platziere, wird es ausgelöst, wenn das Video endet (die Alarmbox erscheint), aber das Video wird nicht minimiert. Daher kam ich zu dem Schluss, dass das Video nicht erreicht werden konnte. Dann änderte ich den Ereignis-Listener wie folgt:

$('#rickieVid').on('ended',function(){ 

     if ($(rect).hasClass("open")){alert('has class')} 
     else {alert('has not');} 
    }); 

Und die Alarmbox zeigt: "hat nicht". Das verwirrt mich wirklich, da die Klasse "offen" mit dem "klickbaren" Ereignis klar hinzugefügt wurde. Kann mir jemand helfen zu verstehen, warum das nicht funktioniert? Vielen Dank P

=================================== bearbeiten ====== ========================

Ich sollte vielleicht erwähnen, dass ich habe versucht, die "rect" Variable außerhalb der " anklickbare“-Funktion es global zu machen, etwa so:

$(document).ready(function(){ 

    var rect; 

    $("#rickie").click(function(){ 

     rect = $(this).next().find('.rect'); 

etc... 

Und dann meine Funktion modifiziert die globale Variable für den Zugriff auf in etwa so:

$('#rickieVid').on('ended',function(){ 

if (rect.hasClass("open")){alert('has class')} 

else {alert('has not');} 

}); 

Which sti ll nicht funktioniert, wie es mit diesem Fehler kommt:

TypeError: undefined is not an object (evaluating 'rect.hasClass') 
+1

Ihre Variable 'rect' ist nur innerhalb der Click-Handler-Funktion verfügbar. – CBroe

+0

Wenn Sie "rect" außerhalb der '.click' Funktion deklarieren, wird rect global sein, so dass Sie es in anderen Funktionen wie dem letzten verwenden können. – xale94

+0

ok so wie mache ich rect global. Ich habe versucht, außerhalb der Funktion an der Spitze der Seite bewegt rect dann zuweist innen, wie so $ (document) .ready (function() { \t var rect; \t $ ("# rickie"). click (function() { \t \t rect = $ (this) .next(). find ('.rect'); – Paul

Antwort

1

Sie können dies erreichen, indem den Last-Ereignishandler das iframe jquery Objekt zugeordnet wird als das Hauptdokument bereit ist, auch wenn die iframe Quelle in es wird geladen und manchmal benötigt auch die Videosteuerung Zeit zum Laden.

Wie auch immer, in diesem Fall müssen Sie das Global Player-Objekt festlegen und auch den beendeten Event-Handler an den Player anhängen.

jQuery-Code zu verwenden:

$(document).ready(function(){ 

     var frame = $("#frame"); 
     var player; 

     frame.bind("load", function() { 
      player = $(this).contents().find("#myVid"); 
      player.on('ended', function() { 
       frame.removeClass("open"); 
       alert('finished'); 
      }); 
     }); 

     $("#clickable").click(function(){ 
      if (frame.hasClass("open")) 
      { 
       frame.removeClass("open"); 
       player[0].pause(); 
      } 
      else { 
       frame.addClass("open"); 
       player[0].play(); 
      } 
     }); 
    }); 

Eine Sache, hier zu beachten. Wenn die iframe-Quelle eine domänenübergreifende URL ist, löst die .contents() einen Sicherheitsfehler aus. Dies funktioniert nur, wenn sich die iframe-Quellseite in derselben Domäne befindet.

+0

Danke Nasir, das ist großartig. Ich habe eine verwandte Frage gestellt, wenn Sie Lust haben, einen Blick darauf zu werfen. http://stackoverflow.com/questions/40471214/how-to-change-variable-depending-on-element-clicked – Paul

+0

Ihr herzlich willkommen. Ich habe in Antwort auf Ihre andere Frage hinzugefügt. Bitte überprüfen Sie, ob es hilft. –