[jQuery] ajouter une image en CSS :before(content)

Résolu
KX Messages postés 19031 Statut Modérateur -  
KX Messages postés 19031 Statut Modérateur -
Bonjour,

En CSS il est possible d'ajouter du contenu au document avec un :before, par exemple une image en faisant comme ceci :

<html>
	<head>
		<style>#img_pro_0:before {content:url(image.png);}</style>
	</head>
	<body>
		<div id="img_pro_0"/>
	</body>
</html>

Ce que je voudrais, c'est faire un script jQuery (que je ne maitrise pas) qui permettrait de générer automatiquement ce ":before" avec une page html qui serait comme ça :

<html>
	<head>
		<script type="text/javascript" src="jquery.js"></script>
		<script>
		
		$(function()
		{
			$('.image_protegee').each(function (num,img)
			{
				$(img).append('<div id="img_pro_'+num+'"/>');
				// ...
			});
		});
		
		</script>
	</head>
	<body>
		<div class="image_protegee" url="image.png"/>
	</body>
</html>

Mon problème est de générer le CSS (ou son équivalent) qui permettrait d'avoir :
#img_pro_0:before {content:url(image.png);}
à partir de la balise que j'obtiens :
<div class="image_protegee" url="image.png"><div id="img_pro_0"/></div>
Évidemment, cela serait fait pour chacune des images 0, 1, 2... que j'aurais déclaré via la classe "image_protegee" comme dans mon exemple.

PS. quand on fait ":before {content:url(image.png);}" le chemin d'accès est relatif au fichier CSS, pas au fichier HTML. Est-ce qu'il est possible de conserver cette propriété avec le script ? Ou du moins faire un chemin relatif au script par exemple, mais surtout éviter que le chemin d'accès à l'image soit relatif à la page HTML...

Si vous avez une solution pour faire ça (ou même une idée) je serais preneur, merci ;-)
--
La confiance n'exclut pas le contrôle

1 réponse

  1. KX Messages postés 19031 Statut Modérateur 3 020
     
    Bonsoir,

    J'ai un peu réussi à avancer, mais j'ai un petit bug.

    Voici comme j'en fait : j'ai rajouté une balise <style> dans le head, et je rajoute ligne par ligne mes :before pour chaque image, il y a peut-être mieux, j'attends vos idées à ce sujet, en attendant voilà ce que ça donne :

    $(function()
    {
        $('head').append('<style id="style_img_pro"/>');
    	
        $('.image_protegee').each(function(num,img)
        {
            $(img).append('<div id="img_pro_'+num+'"/>');
            $('#style_img_pro').append('.image_protegee #img_pro_'+num+':before {content:url("'+$(img).attr('url')+'");}');
        });
    });

    Le bug que j'ai c'est au niveau de la hierarchie des balises.

    En code HTML au départ je mets par exemple ceci :

    <body>
        <p>Avant</p>
        <div class="image_protegee" url="image.png"/>
        <p>Après</p>
    </body>

    J'aurais voulu logiquement obtenir ceci :

    <body>
        <p>Avant</p>
        <div class="image_protegee" url="image.png">
            <div id="img_pro_0"></div>
        </div>
        <p>Après</p>
    </body>

    Mais en réalité j'obtient ceci, ce qui ne convient pas du tout :

    <body>
        <p>Avant</p>
        <div class="image_protegee" url="image.png">
            <p>Après</p>
            <div id="img_pro_0"></div>
        </div>
    </body>

    Je ne vois pas où est le problème... Des idées ?

    Merci...
    0
    1. KX Messages postés 19031 Statut Modérateur 3 020
       
      J'ai corrigé le bug, il s'agissait juste de mes balises "<div/>" qu'il n'aime pas, j'ai mis "<div></div>" et ça fonctionne... Mais du coup j'ai mis wrapInner pour que le contenu de la <div> s'imbrique bien, et remplacé les <div> par des <span> pour que éviter les sauts de ligne. J'ai aussi ajouté un "type" qui vaut soit "before" soit "after" pour spécifier la position de l'image par rapport à ce contenu.

      Au final ça donne donc :

      <html>
          <head>
              <script type="text/javascript" src="jquery.js"></script>
              <script>
              $(function()
              {
                  $('head').append('<style id="style_img_pro"/>');
                  
                  $('.image_protegee').each(function(num,img)
                  {
                      $(img).wrapInner('<span id="img_pro_'+num+'"></span>');
                      $('#style_img_pro').append('.image_protegee #img_pro_'+num
                          +':'+($(img).attr('type')=="after" ? "after" : "before")
                          +' {content:url("img_pro/'+$(img).attr('url')+'");} ');
                  });
              });
              </script>
          </head>
          <body>
              1
              <span class="image_protegee" url="image1.png" type="before">
                  2
                  <span class="image_protegee" url="image2.png" type="after">
                      3
                  </span>
                  4
              </span>
              5
          </body>
      </html>

      Ce qui génère :

      <html>
          <head>
              <script src="jquery.js" type="text/javascript"></script>
              <script>...</script>
              
              <style id="style_img_pro">
      .image_protegee #img_pro_0:before {content:url("img_pro/image1.png");}
      .image_protegee #img_pro_1:after {content:url("img_pro/image2.png");}
              </style>
          </head>
          <body>
              1
              <span class="image_protegee" type="before" url="image1.png">
              <span id="img_pro_0">
                  2
                  <span class="image_protegee" type="after" url="image2.png">
                  <span id="img_pro_1">
                      3
                  </span>
                  </span>
                  4
              </span>
              </span>
              5
          </body>
      </html>

      Et affiche (grosso modo) :

      1 <image1> 2 3 <image2> 4 5
      0