Girando un complesso jquery selettore css in un contesto per la memorizzazione nella cache

StackOverflow https://stackoverflow.com/questions/977185

  •  13-09-2019
  •  | 
  •  

Domanda

Dopo il feedback, riscrittura completa della questione.

Ho il seguente mark up :

<body>
  <h1>Title</h1>
  <p>bla</p>
  <div>
    ... <!-- a thousand tags -->
  </div>

  <div id="do-not-modify-me">
   <!-- a hundred tags -->
  </div>

</body>

Posso accedere a :

  <h1>Title</h1>
  <p>bla</p>
  <div>
    ... <!-- a thousand tags -->
  </div>

Utilizzo :

$('body > *:not(div#do-not-modify-me)');

Faccio in modo che io possa ottenere tutto il contenuto del corpo, tranne il div con id "do-not-modifica-me".

Ora, diciamo che voglio costruire una funzione che lasciare che un altro programmatore per selezionare qualcosa nel corpo, proprio come selezionare con jquery.L'altro programmatore non dovrebbe modificare il div#do-not-modificare-a me, ma lui non dovrebbe preoccupare nessuno.

$('body > *:not(div#do-not-modify-me)') sarà chiamato un sacco di tempo, in modo siamo in cache.

Il idea è :

// TEST CODE

windows.new_body = $('body > *:not(div#do-not-modify-me)');

function select(selector) {
    return $(selector, windows.new_body);
}

Così l'altro programmatore deve essere in grado di fare :

// TEST RESULT CODE
select("p").css("color", "red");

Sarebbe il colore in rosso tutti i <p> nel corpo, ma non quelli contenuti nel div#do-not-modifica-me.

Il CODICE di TEST non funziona, perché, al momento, non vale css() ai bambini del risultato del contesto, non il risultato stesso.

E. G :

select("p").css("color", "red"); 

Si comporta come :

$('body > * p :not(div#do-not-modify-me)').css("color", "red");

Mentre il risultato desiderato sarebbe :

$('body > p :not(div#do-not-modify-me)').css("color", "red");

Nota che :

$('body > * :not(div#do-not-modify-me)').parent().css("color", "red");

Non funziona perché il <p> div#do-not-modifica-mi trasformarsi in rosso.

Come ottenere il risultato in RISULTATO del TEST di CODICE ?È possibile modificare qualsiasi parte del codice.

È stato utile?

Soluzione

Ho rimosso tutti i precedenti di EDIT come non sono più rilevanti, si può leggere nel MODIFICARE la storia.
EDIT3
Fondamentalmente il problema è che non si può memorizzare nella cache il selettore.Che è perché l' $() restituisce gli oggetti corrispondenti, non onu-gli oggetti corrispondenti.Questo significa che l'utilizzo di una cache di selezione significa che la cache è in grado di ottenere la sincronizzazione con il real DOM.I. e.in questa semplice pagina:

<div>
 <p>foo</p><p>bar</p>
</div>
<div class='bar'></div>

.

var context = $('body').children(':not(.bar)'); //this holds: <div><p>foo</p><p>bar</p></div>
$('div', context).append('<p class="x">HAI</p>'); 
//context still is <div><p>foo</p><p>bar</p></div> even though it should be
//<div><p>foo</p><p>bar</p><p class="x">HAI</p></div>

Quindi devi rifare la selezione ogni volta, bassicly si hanno due opzioni:

//reselect the non-editable area everytime
function select(selector) {
  return $(selector, $('body').children(':not(div#do-not-modify-me)') );
}
//or, check the selection against being in the reselectable area.
function select(selector){
  return $(selector).filter(function(){
     return $(this).parents(':not(div#do-not-modify-me)');
  });
}

Si dovrebbe provare a voi stessi che è più veloce.Non credo ci sia altro modo per assicurarsi che non cerca la #do-not-modifica-me div.

Qualcos'altro si potrebbe fare per renderlo ancora più facile (e veloce credo) è di avvolgere l'area modificabile in un div:

<body>
 <div id='modify-me'>
  <h1>Title</h1>
  <!-- thousands of tags -->
 </div>
 <div id='do-not-modify-me'>
  <!--hundreds of tags -->
 </div>
</body>

Quindi si può solo fare

function select(selector) {
  return $(selector, $('#modify-me') );
}

Altri suggerimenti

Hai detto che il codice può essere modificato in qualsiasi modo, giusto? Perché non pensare ad esso come quello che si do vogliono cercare invece di quello che non da ricercare. Mettere il resto del codice in un <div> e basta usare che a seconda del contesto. Non sta andando a vincere alcun premio eleganza, ma è semplice e ottiene il lavoro fatto TM .

Sono abbastanza sicuro che si può semplicemente utilizzare 'contesto' direttamente, in questo modo:

context = $('body > *:not(div#do-not-modify-me)');
context.doStuff();

Dopo aver letto la spiegazione estesa cercherò il mio colpo:

context = $('body > *:not(div#do-not-modify-me)');
$("*:first",context);

Si può anche fare:

  context = $('body > *:not(div#do-not-modify-me)');
  context.find( "*:first");

Per ottenere il numero di elementi che puoi fare:

var len = context.length;

Per accedere all'elemento numero che ho nella collezione si può usare:

context.get(i);

E ci sono tonnellate di informazioni utili su api.jquery.com , anche leggere questo probabilmente vi verrà voglia di creare il proprio selettore.

Modifica
Dopo, ho visto il tuo recente aggiornamento penso che quello che stai cercando è per iterate capacità oltre i risultati contesto elementi, in modo che potrebbe essere fatto, come ho già detto qui diverse volte da:

    for ( var i = 0; i < context.length; ++i)
    {
         $( context[i]).method( );
         // do here you checks, adding, removing.
    }

Questa, non sembra così intelligente, ma dovrebbe funzionare, è possibile incapsulare questa estendendo $ .fn e la funzione di attuazione per il vostro scopo.      Modifica # 2:     
    Proviamo un altro modo:

    (function($)
    {
         $.fn.tagName = function( ) 
         {
             return this.get(0).tagName;
         };
         $.fn.pick = function( tag)
         {
             return this.filter( function( )
             {
                return $(this).tagName == tag;
             });
         };
    }

})(jQuery);

Dopo questo si può fare contex.pick ( "p"), in modo che lo restituisca tutti i paragrafo all'interno del set di risultati, ma questo codice è incompleto, quindi è necessario guardare un po 'più nel codice jQuery, ad esempio per implementare in un modo sarete in grado di utilizzare la funzionalità completa jQuery con funzione di ripresa, probabilmente è necessario prendere in considerazione di utilizzare XPath DOM parser .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top