11521 sujets

JavaScript, DOM et API Web HTML5

Pages :
(reprise du message précédent)

Zut !!! Smiley fache
Je n'ai pas cliqué sur "Envoyer" : désolé !

Voici le code : https://jsfiddle.net/exercices/qb9m1yvo/ :
Après, tu l'adaptes à tes vidéos.


Si tu as besoin d'aide, par exemple pour positionner les checkbox par rapport aux vidéos, tu peux refaire un sujet pour poser ta question : le forum est fait pour !

--------------------------------------------------------------------------------------------------
Quand vous avez trouvé votre réponse, cochez "Résolu" et indiquez la meilleure solution.
Bonjour parsimonhi,
En effet, cela est possible pour une id. Mais pour une class, d'après l'exemple, non !
Quant à générer des id, il est alors impossible de créer la variable player1, player2, étant donné que l'on ne peut pas initialiser
"player"+i=new YT.Player('player',{
   events:{
      'onStateChange':onPlayerStateChange
   }
});
à ma connaissance, bien sûr.

Et puis Mask19 a dit :
Mask19 a écrit :
Après la checkbox peut ne pas avoir de lien direct avec la vidéo, l'utilisateur coche seulement la case quand il a fait une séance.
, donc j'ai fait ça.

J'avais fait un script qui détectais avec onended dans le cas où c'était des <video> mais ce n'est pas le cas.
Mais si tu sais comment utiliser ton script pour des vidéos (au pluriel, car environ 100), tu peux le mettre...
Modérateur
Bonjour,

js_html a écrit :
En effet, cela est possible pour une id. Mais pour une class, d'après l'exemple, non ! Quant à générer des id, il est alors impossible de créer la variable player1, player2 ...


Bla, bla, bla, tu es vraiment de peu de foi ! Pourtant, depuis le temps, tu devrais nous connaitre ! Smiley biggrin Smiley biggrin Smiley biggrin

Les ids, tu les crées à la volée avec js au chargement de la page.

Quant aux variables pour player, il suffit que ce soit les éléments d'une variable player de type tableau (chaque élément du tableau étant relatif à une des vidéos présentes dans la page).

https://jsfiddle.net/parsimonhi/q3r0xh92/ (en vert, les vidéos pas encore vues, en rouge, les vidéos déjà vu, il faut avoir vu la vidéo en entier ou que le curseur de la barre de défilement ait été poussé jusqu'à la fin de la vidéo).

Amicalement,
Super script !

parsimonhi a écrit :
Bla, bla, bla, tu es vraiment de peu de foi ! Pourtant, depuis le temps, tu devrais nous connaitre !
Pourrais-tu réexpliquer s'il te plaît ? Je suis désolé, je ne comprends pas le sens de ces propos ? Je reprécise juste que j'ai écrit que ton script ne s'adaptais pas à ce cas "à ma connaissance, bien sûr.".

Je trouve ton script super, mais je n'en comprends pas un traitre mot.

- "insertBefore" se traduit comment en HTML ?
- "return src.replace(/^.*\/([^?]+)\?.*$/, "$1");", ça sert à quoi ? La regex indique bien les url avec un slash et un point d'interrogation, c'est ça ? Le "$1" sert à quoi ?
- Tu l'initialises où le z ? C'est un object ?
- "forEach" n'est pas un truc peu compatible avec les navigateurs ?
- Dans "if (s) return JSON.parse(localStorage.getItem('alreadySeen'));", s correspond juste à []? Donc c'est true ? C'est bien de mettre un if et son résultat sur la même ligne ? Ce n'est pas mieux d'ouvrir les accolades ? Pourquoi tu parles de JSON là ?

Bref, quand je vois ce script, je me dis que "Je vois bien que tu es passionné et que tu finiras par être bon" ne va peut-être pas arriver. Je suis encore une fois complétement perdu sur une question qui n'est même pas la mienne.

Si tu veux répondre à toutes mes interrogations, tu peux, ça permettra de m'aider à progresser, mais comme tu l'as vu sur d'autres sujets, je suis très long à la compréhension, car tant que je n'ai pas tout compris, je n'ai pas compris... Sinon, tu peux laisser couler, mais je ne progresserai pas. D'ailleurs, je me demande : "Ne faudrait-il pas que j'ouvre un sujet 'Explication du script suivant ?' ?"

Merci beaucoup si tu prends le temps de m'expliquer !
Modérateur
Bonjour,

js_html a écrit :
Super script !

Jusque là, ça va ! Smiley biggrin

js_html a écrit :
Pourrais-tu réexpliquer s'il te plaît ? Je suis désolé, je ne comprends pas le sens de ces propos ? Je reprécise juste que j'ai écrit que ton script ne s'adaptais pas à ce cas "à ma connaissance, bien sûr.".

J'avais vu que tu avais pris la précaution d'écrire "à ma connaissance". C'est bien.

Il faut cependant que tu fasses un peu plus attention quand tu réponds à une question.

Alors que je sais coder "depuis un moment", je suis venu sur Alsacréations sans jamais rien poster pendant presque 10 ans. Je considérais ne pas être prêt. Et même aujourd'hui, je suis encore obligé de faire pas mal de vérifications avant de répondre.

js_html a écrit :
Je trouve ton script super, mais je n'en comprends pas un traitre mot.

Variante 1 : c'est normal, et je m'y attendais,
Variante 2 : ce n'est pas si compliqué que ça et tu finiras par y arriver.

js_html a écrit :

- "insertBefore" se traduit comment en HTML ?

Cette partie du code est tiré de l'exemple donné par les développeurs de youtube. Je n'ai fait que du copier-coller (il s'agit des lignes allant du début du js jusqu'à la ligne contenant le insertBefore()). Cela signifie qu'on insère un élément html juste avant un autre élément dans le DOM. Plus précisément, ici, on insère le script js permettant de faire fonctionner les API youtube avant la 1re balise <script> se trouvant dans la page. On pourrait se passer de ces lignes de code et inclure le script dans le html avant tout autre balise <script> via :
<script src="https://www.youtube.com/iframe_api"></script>


js_html a écrit :
- "return src.replace(/^.*\/([^?]+)\?.*$/, "$1");", ça sert à quoi ? La regex indique bien les url avec un slash et un point d'interrogation, c'est ça ? Le "$1" sert à quoi ?

Cette regex extrait l'identifiant youtube de la vidéo en analysant l'url de l'iframe. L'identifiant est la partie de l'url qui est après un "/" et avant un "?". Le "$1" correspond à la chaine "capturée" entre les parenthèses qui se trouvent dans la regex (ici, "$1" sera donc l'identifiant youtube de la vidéo exactement).

Note : j'aurais peut-être dû écrire
return src.replace(/^.*\/([^\/?]+)\?.*$/, "$1");

Cela semble plus propre. Et du coup, j'ai modifié le jsfiddle.

js_html a écrit :
- Tu l'initialises où le z ? C'est un object ?

Dans le code des fonctions, il est en paramètre de ces fonctions. Il est donc initialisé par le code qui appelle ces fonctions.

Dans le forEach(), c'est un peu particulier : z prend à tour de rôle la valeur de chaque élément du tableau pour lequel on fait un forEach().

On aurait pu utiliser n'importe quel autre nom pour la variable z.

js_html a écrit :
- "forEach" n'est pas un truc peu compatible avec les navigateurs ?

On est en 2021. On peut utiliser forEach() selon moi.

js_html a écrit :
- Dans "if (s) return JSON.parse(localStorage.getItem('alreadySeen'));", s correspond juste à []? Donc c'est true ?

Ce if(s) n'est utile que si le local storage n'a pas encore servi pour ce script. localStorage.getItem('alreadySeen') renvoie dans ce cas "null" et c'est ce que ce if(s) teste.

js_html a écrit :
C'est bien de mettre un if et son résultat sur la même ligne ?

Y en a qui mettent l'ensemble de leur code js sur une seule ligne. Smiley cligne

Blague mise à part, c'est surtout une question de lisibilité. C'est à chacun de voir ce qu'il préfère. Pour ma part, je n'aime pas trop les codes qui s'étalent sur plein de lignes (en théorie, jamais plus d'une page écran pour une fonction). Mettre les if() et leur "résultat" sur la même ligne permet parfois de diminuer sensiblement le nombre de lignes d'une fonction. On perd un peu en lisibilité parce que la ligne est plus longue, mais on en gagne aussi pas mal parce qu'il y a moins de lignes dans la fonction dans laquelle ils se trouvent.

EDIT: mais on ne le fait bien sûr que si la ligne est relativement courte.

js_html a écrit :
Ce n'est pas mieux d'ouvrir les accolades ?

Selon moi, ici, non.

js_html a écrit :
Pourquoi tu parles de JSON là ?

Dans le localStorage, on stocke une paire (identifiant, chaine de caractère). Mais le contenu que l'on veut stocker est un tableau. JSON.parse() et JSON.stringify() permettent de transformer une chaine de caractère extraite du localStorage en un tableau js, et de transformer un tableau js en chaine de caractères pour le stocker dans le localStorage.

js_html a écrit :
Bref, quand je vois ce script, je me dis que "Je vois bien que tu es passionné et que tu finiras par être bon" ne va peut-être pas arriver. Je suis encore une fois complètement perdu sur une question qui n'est même pas la mienne.

C'est rien. Ça passera ! Smiley lol Smiley lol Smiley lol

Amicalement,
Modifié par parsimonhi (25 Feb 2021 - 06:02)
Merci pour ces explications !

a écrit :
Il faut cependant que tu fasses un peu plus attention quand tu réponds à une question.
C'est ce que j'ai fait : j'ai cherché à adapter ton script mais je n'y arrivais pas, alors j'ai proposé un script (minable par rapport au tien) qui fonctionnait.

Pourquoi faut-il quitter le script Youtube soit le premier ?

Comment on a dit que $1 était la chaîne capturée ?

z est toujours en paramètre, sauf dans les forEach. Je n'arrive pas à discerner l'endroit où l'on a dit ce qu'il y avait dedans.


Merci !
Modérateur
Bonjour,

js_html a écrit :
Pourquoi faut-il que le script Youtube soit le premier ?

Parce que les scripts suivants dans la page ont éventuellement besoin que ce script Youtube soit exécuté avant.

js_html a écrit :
Comment on a dit que $1 était la chaîne capturée ?

Dans une expression régulière, tout ce qui est entre deux parenthèses est "capturé" et rangé automatiquement dans des sortes de variables $1, $2, $3 ... (ce qui est entre le premier couple de parenthèses est mis dans $1, ce qui est entre le deuxième couple de parenthèses dans $2, etc.).

js_html a écrit :
z est toujours en paramètre, sauf dans les forEach. Je n'arrive pas à discerner l'endroit où l'on a dit ce qu'il y avait dedans.

De quelle ligne de code tu parles ?

Amicalement,
Merci, je comprends mieux !

a écrit :
Je n'arrive pas à discerner l'endroit où l'on a dit ce qu'il y avait dedans.
Je parle dans tout le script...

D'ailleurs, on ne dirait presque pas que ce n'est pas mon sujet... Smiley lol
Par contre, il faudra faire attention de prévenir les utilisateurs que le cadre sera rouge seulement s'ils regardent la vidéo jusqu'à la toute fin (ce que personne ne fait) ou qu'ils poussent le curseur jusqu'à la toute fin.
Mais je pense qu'il serait mieux de détecter lorsque la vidéo a commencé plutôt...
Modérateur
Bonjour,

js_html a écrit :
Je parle dans tout le script...


Misère. Je ne sais même pas pourquoi on te laisse encore faire du javascript. Te laisser regarder un ordinateur (même de loin), c'est peut-être déjà trop ! Smiley lol

Bref, il me semble que là, tu exagères. De la part d'un débutant, on aurait pu le comprendre. Mais tu n'es plus un débutant. Cela fait des mois (au moins) que tu as commencé, et tu as déjà plusieurs centaines de posts ici, avec parfois des questions qui étaient dans la catégorie difficile. On s'attend à ce que tu aies compris ce qu'est le paramètre d'une fonction. Pour le forEach(), admettons que tu découvres, mais il suffirait que tu fasses un script de 3 lignes pour tester et normalement, après, c'est bon, tu devrais avoir compris.

On commence par la fin.

1)
videos.forEach(z => setYT(z));

La variable videos a été initialisée plus haut dans le script et contient la liste des éléments html iframes (contenant les videos youtube) se trouvant dans la page. J'espère que jusque là, ça va.

Le forEach() parcourt en boucle la liste de ces iframes, comme je l'ai déjà écrit dans ma réponse précédente. À chaque boucle, z vaut donc l'un des éléments html iframe de la page. Ce code est équivalent à :

for(let k=0;k<videos.length;k++) setYT(videos[k]);

z dans le forEach() vaut la même chose que videos[k] dans le for().

L'intérêt évident du forEach() est qu'il est plus concis.

2)
function setYT(z) {
  player[z.id].player = new YT.Player(z.id, {
    events: {
      'onStateChange': player[z.id].onPlayerStateChange
    }
  });
}

La fonction setYT() est utilisée dans le forEach() précédent. z, qui est le paramètre de la fonction, vaut donc à l'intérieur de setYT() un élément html de type iframe (un élément différent à chaque boucle du forEach()).

3)
videos.forEach(z => setPlayer(z));

Pareil que pour le 1), sauf qu'on appelle setPlayer() au lieu de setYT(). z vaut un élément html de type iframe.

4)
function setPlayer(z) {
  z.id = ytId(z);
  ...
}

Pareil que pour le 2). z vaut un élément html de type iframe.

5)
function ytId(z) {
  var src = z.getAttribute('src');
  return src.replace(/^.*\/([^\/?]+)\?.*$/, "$1");
}

La fonction est appelée par setPlayer() à la ligne z.id = ytId(z);

Le z qui est en paramètre de setPlayer() est un élément html de type iframe. Il est transmis à la fonction ytId() via la ligne z.id = ytId(z); qui se trouve dans setPlayer(). Et du coup, le z à l'intérieur de ytId() est aussi un élément html de type iframe.

En résumé, z est initialisé dans les forEach() en prenant successivement la valeur de chaque élément iframe de la page, et est transmis aux autres fonctions via le paramètre de ces fonctions, que l'on a partout appelé z, mais que l'on aurait pu appeler autrement, et on aurait même pu choisir un nom différent pour chaque fonction.

Amicalement,
Modifié par parsimonhi (25 Feb 2021 - 11:16)
Modérateur
Bonjour,

js_html a écrit :
Par contre, il faudra faire attention de prévenir les utilisateurs que le cadre sera rouge seulement s'ils regardent la vidéo jusqu'à la toute fin (ce que personne ne fait) ou qu'ils poussent le curseur jusqu'à la toute fin.
Mais je pense qu'il serait mieux de détecter lorsque la vidéo a commencé plutôt...

Oui, tout à fait.

Ou bien on peut aussi imaginer avoir 3 couleurs. Vert = jamais vu, Orange = commencé mais pas entièrement vu, Rouge = vu entièrement.

Il ne te reste plus qu'à faire le script. Smiley cligne

Pour tester si une vidéo a commencé, c'est if (e.data == YT.PlayerState.PLAYING) au lieu de if (e.data == YT.PlayerState.ENDED) qu'il faut utiliser. Si tu conserves le système à 2 couleurs, il devrait suffire de remplacer l'un par l'autre.

Dans le cas où on souhaite un système à 3 couleurs, il faudra mettre dans le local storage la liste des vidéos commencées en plus de la liste des vidéos entièrement lues. Et le code pour gérer ça sera globalement un peu plus complexe aussi.

Amicalement,
Modérateur
Bonjour,

js_html a écrit :
...lors j'ai proposé un script (minable par rapport au tien) qui fonctionnait.

Je ne dirais pas ça. Ton script me semble fonctionner pas trop mal et a le mérite de la simplicité.

Mask19 a écrit :
Ah mince, je comprends pas pourquoi mais dés que j'actualise, elle est décochée ????

C'est bizarre en effet. Normalement, le script de js_html fonctionne et tu ne devrais pas observer ça ... sauf si le local storage est ré-initialisé à chaque actualisation par ton navigateur.

Sur quoi tu testes ? Quelle machine et quel navigateur ? As-tu essayé sur d'autres machines et navigateurs ?

Amicalement,
a écrit :
Misère. Je ne sais même pas pourquoi on te laisse encore faire du javascript. Te laisser regarder un ordinateur (même de loin), c'est peut-être déjà trop !
Ce n'est pas très sympathique de ta part... Smiley bawling Smiley bawling Smiley bawling

a écrit :
On s'attend à ce que tu aies compris ce qu'est le paramètre d'une fonction.
C'est le cas. En fait, le problème est que je n'avais pas compris le forEach(). Dans
forEach(z => setYT(z));
, je n'avais pas compris que le z était le nombre qui changeait (comme i ou k dans for) : j'avais compris que c'était la liste. Tu vas ici me dire : "Ce n'était pas ça le code : il y avait 'videos.' au début ! Smiley lol ". Je te réponds : "Je ne l'avais pas vu ! Smiley bawling "

Maintenant, avec tes explications détaillées, j'ai compris : Smiley merci !

a écrit :
appelé z, mais que l'on aurait pu appeler autrement, et on aurait même pu choisir un nom différent pour chaque fonction
Oui, ça je sais.


a écrit :
Il ne te reste plus qu'à faire le script.
Moi ? js_html ? Ou tu parlais de Mask19 ? Oui, je peux essayer si tu parlais de moi.


[i]Mask19, tu préfères un système à deux couleurs ? Pas commencé et commencé ? Ou pas fini et fini ?
Ou trois couleurs ? Jamais vu et commencé et fini ?
[/b]

PS : C'est pénible le BBCode : on ne peut pas mettre en italique et en gras, ni mettre un lien avec de l'italique ou du gras... Smiley bawling Smiley bawling
Modifié par js_html (25 Feb 2021 - 11:18)
Effectivement, Mask19, c'était la deuxième raison pour laquelle je n'avais pas adapté le script de parsimonhi, mais je ne m'en suis plus souvenu...
Modérateur
Bonjour,

js_html a écrit :
Ce n'est pas très sympathique de ta part...

Qui aime bien châtie bien !

js_html a écrit :
Moi ? js_html ? Ou tu parlais de Mask19 ? Oui, je peux essayer si tu parlais de moi.

Oui, je parlais de toi, js_html. Tu dois pouvoir y arriver.

Amicalement,
Modifié par parsimonhi (25 Feb 2021 - 11:21)
parsimonhi, du coup, vu qu'avec DailyMotion ça ne fonctionne pas, faut-il quand même que j'essaie de l'adapter ou dans tout les cas, ça ne fonctionnera pas pour son usage et ce n'est pas utile ?

PS : Ton message prouve quecest pénible le BBCode : on ne peut pas mettre en italique et en gras, ni mettre un lien avec de l'italique ou du gras et pareil pour les citations... Smiley bawling Smiley bawling
Pages :