Necesita un gurú js que me ayude con esto

  • mindfullsilence
  • Professor
  • Professor
  • Avatar de Usuario
  • Registrado: Ago 04, 2008
  • Mensajes: 846
  • Status: Offline

Nota Agosto 4th, 2011, 8:29 pm

Así que Ive decidió que chupar en javascript. Im así trabajando en un proyecto personal mejor. Im tratando de crear un script autoclose voluntad un elemento html que ha sido escrito en un textarea. Ive llegado tan cerca y, a continuación, me golpeó un muro de ladrillo. Puede ver el ejemplo aquí: demo.

Es lo que debería para suceder es que la secuencia de comandos se ejecuta cada vez que alguien golpea la backslash("/"). Después de que se desencadene el evento, debe anexar todo lo que es el último elemento abierto.
Im cargar mi texto en la función hasta donde está situado el cursor. A continuación, encontrar todos los elementos html y les pegue en una matriz que se inserta en otra función. La segunda función coincide cada elemento en pares y escupe el resto (la etiqueta abierta).
Puede ver la secuencia de comandos: script

Mi problema es que si incrustar un par de elementos y Inicio cerrarlas, termino con algo como "<///p>" en lugar de "</p>".
¿Alguna idea?
Use your words like arrows to shoot toward your goal.
  • Anonymous
  • Bot
  • No Avatar
  • Registrado: 25 Feb 2008
  • Mensajes: ?
  • Loc: Ozzuland
  • Status: Online

Nota Agosto 4th, 2011, 8:29 pm

  • SpooF
  • ٩๏̯͡๏۶
  • Bronze Member
  • Avatar de Usuario
  • Registrado: May 22, 2004
  • Mensajes: 3415
  • Loc: Richland, WA
  • Status: Offline

Nota Agosto 4th, 2011, 11:54 pm

Que a través de este conjunto. Creo que funciona.

JAVASCRIPT Código: [ Select ]
function priorElement(html,cursor_pos){
 
    var re = /<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>/gi
    var matches = html.match(re,html)
 
    var elements = [];
    var positions = [];
 
    // Run through all the matches
    for ( x in matches )
    {
        // Strip all the randon stuff so we just have the element.
        var stripped_element = matches[x].replace(/\s[^\/>]+/g,'');
 
        // If it has a trailing backslash ignore it
        if(stripped_element.match(/\w\//)) // may want to look for these instead like in your script area|base|basefont|br|hr|input|img|link|meta
            continue;
 
        // Get rid of the `>` so we can match Ex. <a href="" class=""> turns, we need to
        // matchs `<a` and not `<a>`    
        var stripped_element = stripped_element.substring(0,stripped_element.length-1)
 
        positions.push(html.search(stripped_element));
        elements.push(stripped_element);
 
    }
 
    if(positions && elements) {
       
        var element = 0;
        for(var i in positions)
        {
            if(positions[i] > cursor_pos)
            {
                // Find the element right before our cursor
                element = i - 1;
                break;
            }
        }
 
        if(elements[element] == undefined)
            return;
 
        // return just the element, a, center, div, span...
        return elements[element].replace(/[\<\/\>]/,'');
    }
    return;
}
  1. function priorElement(html,cursor_pos){
  2.  
  3.     var re = /<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>/gi
  4.     var matches = html.match(re,html)
  5.  
  6.     var elements = [];
  7.     var positions = [];
  8.  
  9.     // Run through all the matches
  10.     for ( x in matches )
  11.     {
  12.         // Strip all the randon stuff so we just have the element.
  13.         var stripped_element = matches[x].replace(/\s[^\/>]+/g,'');
  14.  
  15.         // If it has a trailing backslash ignore it
  16.         if(stripped_element.match(/\w\//)) // may want to look for these instead like in your script area|base|basefont|br|hr|input|img|link|meta
  17.             continue;
  18.  
  19.         // Get rid of the `>` so we can match Ex. <a href="" class=""> turns, we need to
  20.         // matchs `<a` and not `<a>`    
  21.         var stripped_element = stripped_element.substring(0,stripped_element.length-1)
  22.  
  23.         positions.push(html.search(stripped_element));
  24.         elements.push(stripped_element);
  25.  
  26.     }
  27.  
  28.     if(positions && elements) {
  29.        
  30.         var element = 0;
  31.         for(var i in positions)
  32.         {
  33.             if(positions[i] > cursor_pos)
  34.             {
  35.                 // Find the element right before our cursor
  36.                 element = i - 1;
  37.                 break;
  38.             }
  39.         }
  40.  
  41.         if(elements[element] == undefined)
  42.             return;
  43.  
  44.         // return just the element, a, center, div, span...
  45.         return elements[element].replace(/[\<\/\>]/,'');
  46.     }
  47.     return;
  48. }
#define NULL (::rand() % 2)
  • mindfullsilence
  • Professor
  • Professor
  • Avatar de Usuario
  • Registrado: Ago 04, 2008
  • Mensajes: 846
  • Status: Offline

Nota Agosto 5th, 2011, 1:56 pm

Quería que los elementos a ser cerrado en sucesión. Por lo que si he integrado elementos, la función cerrará en orden. Ejemplo:
HTML Código: [ Select ]
<div>
<p>
<a>
 
  1. <div>
  2. <p>
  3. <a>
  4.  

Si tuviera que escribir "&lt; /" el resultado sería:
  • Por primera vez: un
  • Segundo tiempo: p
  • Tercer tiempo: div

Ive adaptado su código, de simulación y casi tienen que trabajar. El único problema es que con elementos incrustados tal como se muestra más arriba, el resultado es como sigue:
  • Por primera vez: un
  • Segundo tiempo: una
  • Tercer tiempo: p
  • Cuarto tiempo: div
¿Alguna idea? demo
Use your words like arrows to shoot toward your goal.
  • mindfullsilence
  • Professor
  • Professor
  • Avatar de Usuario
  • Registrado: Ago 04, 2008
  • Mensajes: 846
  • Status: Offline

Nota Agosto 8th, 2011, 12:36 am

Ive hizo algunos cambios en mi código que sigue una lógica mejor pero todavía estoy atascado con prácticamente el mismo problema.

Heres el código que tengo hasta ahora:
JAVASCRIPT Código: [ Select ]
function unclosed(html,cursor_pos){
 
   //Remove any text after the cursor
   html = html.substr(0,cursor_pos);
   var re = /<[^<]+?>/gi
   var matches = html.match(re,html)
   var openers = [];
   var closers = [];
   var unclosed = [];
   
   // Run through all the matches
   for ( x in matches )
   {
      // Strip all the random stuff so we just have the element.
      var stripped_element = matches[x].replace(/\s[^\/>]+/g,'');
     
      // If it has a trailing backslash ignore it, since it's slef-closing
      if(stripped_element.match(/\w\//))
         continue;
 
      // Get rid of the `>` so we can match, we need to match `<a` and not `<a>`  
      var stripped_element = stripped_element.substring(0,stripped_element.length-1);
      stripped_element = stripped_element.replace("<","");
     
      // now we check to see if it is a closing element or not
      if(stripped_element.match(/\//))
      {
         //if it is, stick it in the "closers" array
         closers.push(stripped_element);
      }
      else
      {
         //otherwise put it in the "openers" array
            openers.push(stripped_element);
      }
   }
   
   // if there are just as many closing tags as there are opening tags
   // than all tags are closed, so return false.
   if(openers.length == closers.length || openers.length == 0)
   {
      return false;
   }
   
   // if the closers array is empty, push the openers to the
   // "unclosed" array and return the last entry
   else if(closers.length == 0 && openers.length > 0) {
      for ( x in openers )
      {
         unclosed.push(openers[x]);
      }
      return unclosed.pop();
   }
   
   // now we check for matches between opening and closing tags.
   else
   {
      // go through each entry in the "openers" array
      for (x in openers)
      {
         hasClose = new RegExp("\/"+openers[x],"gi");
         
         // see if theres a match for it in the "closers" array
         for (i in closers)
         {
            // if there is, remove the match from both arrays
            // and constinue to the next entry.
            if(closers[i].match(hasClose))
            {
               closers.splice(i,1);
               openers.splice(x,1);
               break;
            }
           
            // if there's not, add the "openers" entry to the
            // "unclosed" array
            else
            {
               unclosed.push(openers[x]);
            }
         }
      }
   // now return the last entry in the "unclosed" array.
   return unclosed.pop();
   } 
}
 
  1. function unclosed(html,cursor_pos){
  2.  
  3.    //Remove any text after the cursor
  4.    html = html.substr(0,cursor_pos);
  5.    var re = /<[^<]+?>/gi
  6.    var matches = html.match(re,html)
  7.    var openers = [];
  8.    var closers = [];
  9.    var unclosed = [];
  10.    
  11.    // Run through all the matches
  12.    for ( x in matches )
  13.    {
  14.       // Strip all the random stuff so we just have the element.
  15.       var stripped_element = matches[x].replace(/\s[^\/>]+/g,'');
  16.      
  17.       // If it has a trailing backslash ignore it, since it's slef-closing
  18.       if(stripped_element.match(/\w\//))
  19.          continue;
  20.  
  21.       // Get rid of the `>` so we can match, we need to match `<a` and not `<a>`  
  22.       var stripped_element = stripped_element.substring(0,stripped_element.length-1);
  23.       stripped_element = stripped_element.replace("<","");
  24.      
  25.       // now we check to see if it is a closing element or not
  26.       if(stripped_element.match(/\//))
  27.       {
  28.          //if it is, stick it in the "closers" array
  29.          closers.push(stripped_element);
  30.       }
  31.       else
  32.       {
  33.          //otherwise put it in the "openers" array
  34.             openers.push(stripped_element);
  35.       }
  36.    }
  37.    
  38.    // if there are just as many closing tags as there are opening tags
  39.    // than all tags are closed, so return false.
  40.    if(openers.length == closers.length || openers.length == 0)
  41.    {
  42.       return false;
  43.    }
  44.    
  45.    // if the closers array is empty, push the openers to the
  46.    // "unclosed" array and return the last entry
  47.    else if(closers.length == 0 && openers.length > 0) {
  48.       for ( x in openers )
  49.       {
  50.          unclosed.push(openers[x]);
  51.       }
  52.       return unclosed.pop();
  53.    }
  54.    
  55.    // now we check for matches between opening and closing tags.
  56.    else
  57.    {
  58.       // go through each entry in the "openers" array
  59.       for (x in openers)
  60.       {
  61.          hasClose = new RegExp("\/"+openers[x],"gi");
  62.          
  63.          // see if theres a match for it in the "closers" array
  64.          for (i in closers)
  65.          {
  66.             // if there is, remove the match from both arrays
  67.             // and constinue to the next entry.
  68.             if(closers[i].match(hasClose))
  69.             {
  70.                closers.splice(i,1);
  71.                openers.splice(x,1);
  72.                break;
  73.             }
  74.            
  75.             // if there's not, add the "openers" entry to the
  76.             // "unclosed" array
  77.             else
  78.             {
  79.                unclosed.push(openers[x]);
  80.             }
  81.          }
  82.       }
  83.    // now return the last entry in the "unclosed" array.
  84.    return unclosed.pop();
  85.    } 
  86. }
  87.  


El problema está en la tercera etiqueta html incrustado. En lugar de este resultado:
HTML Código: [ Select ]
<div><p><a>
</a></p></div>
 
  1. <div><p><a>
  2. </a></p></div>
  3.  

Im obtener esto:
HTML Código: [ Select ]
<div><p><a>
</a></p></p>
 
  1. <div><p><a>
  2. </a></p></p>
  3.  
Use your words like arrows to shoot toward your goal.

Publicar Información

  • Total de mensajes en este tema: 4 mensajes
  • Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 136 invitados
  • No puede abrir nuevos temas en este Foro
  • No puede responder a temas en este Foro
  • No puede editar sus mensajes en este Foro
  • No puede borrar sus mensajes en este Foro
  • No puede enviar adjuntos en este Foro
 
 

© 2011 Unmelted, LLC. Ozzu® es una marca registrada de Unmelted, LLC