Bonjour,
J'ai une liste de vidéos Youtube avec ce type de lien
<a href="https://youtu.be/z7Pq2N1aFM8">Le loup et les trois soeurs</a>
Je voudrais pouvoir récupérer la référence de la vidéo (ici z7Pq2N1aFM8)
pour l'afficher ailleurs sur le site dans un iframe sous la forme :
https://www.youtube.com/embed/z7Pq2N1aFM8[/url

Smiley confus Est-ce possible ?
Merci
Salut,

Il nous faudrait plus de contexte. Tu les as où ces liens ? Et tu codes avec quoi ?

A priori cela doit être possible avec une expression régulière, mais je dirais que ce n'est pas lié à la section css du forum.
Bonjour,

Bien sûr que c'est possible. Maintenant il nous faut connaître le contexte. Par exemple : ces liens dont il est question, doivent-ils être analysés côté front-end ou côté backend ? Si côté backend, alors analyse du contenu sous forme d'un string, directement. Mais vient aussi la question du langage utilisé... PHP ? Ensuite seulement on pourra répondre à la question.

En attendant voici un exemple de regex qui devrait fonctionner avec la plupart des langages, ici la fonction est tirée de JavaScript (je suis sous Node.js, chez moi le JavaScript ça marche partout, aussi bien en back qu'en front, mais ce n'est pas dur à adapter en PHP) :
const test = leContenudeMonString.match(/href="https?:\/\/youtu.be\/(.*?)"/g);
console.log(test); // => renvoie un tableau

La parenthèse capture l'ID de la vidéo.

Voir la regex en action ici : Regex101.

La capture `href="` ce n'est pas obligatoire, c'est juste pour assurer une spécificité plus importante dans le string analysé.

Par contre, bien que ce type d'URLs pour Youtube fonctionne, ce n'est pas le format habituel, d'ailleurs on a droit à une redirection 301. Perso j'ai plus l'habitude des URLs comme ceci :
https://www.youtube.com/watch?v=z7Pq2N1aFM8

Ce qui me conduit à faire des choses plutôt comme ceci :
/href="https?:\/\/www.youtube.com\/watch\?v=(.*?)"/g

Après, du moment que vous récupériez votre ID... C'est plutôt pour le pointage des liens de base que c'est mieux.
Modifié par Olivier C (15 Mar 2024 - 13:22)
Administrateur
Bonjour,

Il faut vraiment le contexte comme demandé.
Perso c´est dans la console navigateur ou après avoir copié le DOM dans VSCodium que je dois extraire ceci ou cela et c´est un usage moins courant qu´un script JS ou serveur Smiley lol

Dans la console (F12, Ctrl-Maj-K), en reprenant la regex d´Olivier C, on peut afficher un tableau ainsi :
resultat = [];
Array.from($$('[href^="https://youtu.be"]')).forEach(elt => {
  resultat.push({
    elt,
    ref: elt.getAttribute('href').replace( /https?:\/\/youtu.be\/(.*?)/g, "$1" )
  })
});
console.table(resultat);

Modifié par Felipe (15 Mar 2024 - 14:52)
Je connaissais pas $$, c'est un raccourci pour [...document.querySelectorAll( )] ?
( Array.from() n'a pas l'air utile )
@Mathieuu : un hommage à jQuery peut-être ?
Quand je vois le nombre de fois où j'ai recours à document.querySelector et document.querySelectorAll (actuellement 128 utilisations pour mes scripts fronts)... des fois j'y songe à me faire une petite fonction passe partout (mais ce serait moins portable)...
En quoi serait-ce moins portable ?
Voici ma bibliothèque de fonctions simplifiant les manipulations du DOM

function $(id) {
  return document.getElementById(id);
}
function $$(selector, element) {
  if(!element) element = document;
  return element.querySelector(selector);
}
function $$$(selector, element) {
  if(!element) element = document;
  return element.querySelectorAll(selector);
}
function newNode(tag = '', ...params) {
  let node;
  if(tag) node = document.createElement(tag);
  else node = document.createDocumentFragment();
  for(let param of params) AddToNode(node, param);
  return node;
}
function AddToNode(node, ...params) {
  for(let param of params) {
    switch(typeof param) {
      case 'undefined':
        break;
      case 'object':
        if(!param) break;
        if(isArray(param)) {
          for(let item of param) AddToNode(node, item);
          break;
        }
        if(param) node.appendChild(param);
        break;
      default:
        param = '' + param;
        let classMatch = param.match(/^\.([a-z][-a-z0-9]*)$/i);
        if(classMatch) {
          node.classList.add(classMatch[1]);
          break;
        }
        let idMatch = param.match(/^#([-_a-z0-9]+)$/i);
        if(idMatch) {
          node.id = idMatch[1];
          break;
        }
        let attrMatch = param.match(/^([-a-z0-9]+)=(.*)$/);
        if(attrMatch) {
          let attrName = attrMatch[1], attrValue= attrMatch[2] || '';
          node.setAttribute(attrName, attrValue);
          break;
        }
        switch(param) {
          case '/': case 'br': case '\n':
            node.appendChild(newNode('br'));
            break;
          default:
            node.appendChild(document.createTextNode(param));
        }
    }
  }
}
Modérateur
C'est probablement moins portable pour un tiers qui n'a pas repéré qu'il ne s'agissait pas de fonction de jQuery
J'avais tester aussi comment faire quelque chose du même genre pour réduire document.querySelector a un simple caractère Smiley smile https://codepen.io/gc-nomade/pen/poWzaGm . Test sans suite...

@PapyJp, merci pour le partage.
Merci à vous deux pour votre intervention respective. Ça me fait vraiment réfléchir. Je me demande si je ne vais pas passer à l'action dans ce sens pour ma prochaine révision front.
C'est vrai que c'est sympa. Je pense que je vais mettre en place cette idée avec la dénomination de qcyrillus (car j'y avais déjà réfléchit précédemment et était arrivé à la même conclusion : "$" pour unique, "$$" pour plusieurs). Mais la définition optionnelle de l'élément est une caractéristique importante, je pioche donc aussi chez Papy :
const $ = (selector, element = document) => element.querySelector(selector)
const $$ = (selector, element = document) => element.querySelectorAll(selector) // => [object NodeList]
const $$$ = (selector, element = document) => [...element.querySelectorAll(selector)] // => [object Array]

CodePen

Voilà mon idée pour l'instant. Je fais mon japonnais des années 50, copieur des technos de l'occident...
Modifié par Olivier C (16 Mar 2024 - 23:33)
Modérateur
Bonjour,

Olivier C a écrit :
Je fais mon japonais des années 50, copieur des technos de l'occident...
1) Quitte à faire le japonais, pourquoi ne pas utiliser des kanjis comme nom de fonction ? Comme il y a des tonnes de kanjis, on peut espérer que le nom des fonctions puisse ne jamais faire plus de un caractère. Et puis il n'y a pas que les kanjis comme caractères exotiques. On a vraiment un grand choix.

2) Le choix de $ me semble maladroit vu que jquery existe. Si jquery n'existait pas, on ne pourrait que plussoyer. Mais voilà, il existe. Et si à un moment ou à un autre on a besoin d'une librairie quelconque "trop géniale" qui elle-même utilise jquery (y en a pas juste une ou deux sur Terre), ou bien si on fournit soi-même aux autres une librairie "trop géniale" qu'on a mis des années à mettre au point et basée sur ces magnifiques fonctions maison commençant par $, bah, on sera (ou les autres seront) "dedans" ! Smiley cligne

3) Quand on encapsule une fonction dans une autre, on risque de perdre en performance. On le voit d'ailleurs avec jquery qui fait perdre tranquillou un facteur de disons environ 2 (à la louche) par rapport à du js vanilla équivalent (sans compter le téléchargement du code de jquery). J'ai donc fait le test suivant :
function $(selector, element = document) {
  return element.querySelector(selector);
}
let e,t0,t1,t2;
t0 = performance.now()
for(let k=0;k<100000;k++) e=$(`p:nth-of-type(${k})`);
t1 = performance.now();
console.log(`It took ${t1 - t0} milliseconds.`);
t1 = performance.now();
for(let k=0;k<100000;k++) e=document.querySelector(`p:nth-of-type(${k})`);
t2 = performance.now();
console.log(`It took ${t2 - t1} milliseconds.`);

Et curieusement, $() employée un grand nombre de fois est aussi rapide (voire légèrement plus rapide) que document.querySelector() !

Conclusion
Ça parait une bonne idée, ces fonctions de raccourci, mais s'il y a bien un caractère à éviter pour en construire leur nom, c'est $. N'importe quoi d'autre, c'est mieux.

Amicalement,
Modifié par parsimonhi (17 Mar 2024 - 07:15)
Merci d'avoir créé un test, je me posais la question des perfs justement. Mais cela ne m'étonne pas qu'il n'y ait pas d'impact car la fonction est ultra basique.

Ce qui plombe les perfs dans jQuery c'est que son sélecteur était un couteau Suisse : là où nous utilisons trois sélecteurs, jQuery utilise un unique sélecteur, analyse si les données reçues sont un item unique, un tableau ou une liste de nœuds et propose un traitement en conséquence (il y a le poids de la librairie aussi, mais ça c'est encore autre chose).

Il y a la polémique, tout à fait légitime autour du nom de la fonction. Chez moi l'utilisation du "$" n'est pas un frein : dans mon cas, utiliser jQuery ou une bibliothèque qui en dépend serait une mauvaise pratique de toute façon (j'ai bien dit "dans mon cas").
Modérateur
Bonjour,
Olivier C a écrit :
Merci d'avoir créé un test, je me posais la question des perfs justement. Mais cela ne m'étonne pas qu'il n'y ait pas d'impact car la fonction est ultra basique.
Justement, plus la fonction est basique, plus il peut y avoir un impact. Ce qui "coûte" quand on emploie une fonction intermédiaire, c'est le démarrage de la fonction (analyse des paramètres, mais aussi plein d'autres petites choses). Plus le corps de la fonction est petit, plus le coût du démarrage est proportionnellement important.

C'est pourquoi j'ai été vraiment surpris par le résultat du test.

Amicalement,
J'ai refais quelques tests, je trouve assez étrange cette fonction $$
Si j'essaie de m'en servir directement ça m'envoie boulet ( Uncaught ReferenceError: $$ is not defined ).
Par contre elle fonctionne bien sans que je la définisse si j'essaye de m'en servir dans la console du navigateur web..

Moi qui utilise souvent la console pour vérifier que mon code fonctionne avant de le mettre dans mes fichiers... je trouve ça pas folichon que des fonctions n'existent que dans la console Smiley ohwell