Frage

Nach Rückmeldung vollständige Neuformulierung der Frage.

Ich habe folgende Markierung:

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

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

</body>

Ich kann darauf zugreifen:

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

Verwendung:

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

Ich mache das, damit ich den gesamten Inhalt des Körpers außer dem Div mit der ID „do-not-modify-me“ erhalten kann.

Nehmen wir nun an, ich möchte eine Funktion erstellen, die es einem anderen Programmierer ermöglicht, alles im Textkörper auszuwählen, genau wie die Auswahl mit jquery.Der andere Programmierer sollte div#do-not-modify-me nicht ändern, aber er sollte sich auch nicht darum kümmern müssen.

$('body > *:not(div#do-not-modify-me)') wird viel Zeit aufgerufen, also werden wir es zwischenspeichern.

Der Idee Ist :

// TEST CODE

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

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

Der andere Programmierer sollte also in der Lage sein:

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

Es würde sich immer rot färben <p> im Körper, aber nicht die in div#do-not-modify-me enthaltenen.

Der TESTCODE funktioniert nicht, da er derzeit css() auf die untergeordneten Elemente des Kontextergebnisses anwendet, nicht auf das Ergebnis selbst.

Z.B :

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

Benimmt sich wie :

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

Das gewünschte Ergebnis wäre zwar:

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

Beachten Sie, dass :

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

Funktioniert nicht, weil die <p> div#do-not-modify-me wird rot.

Wie würden Sie das Ergebnis im TEST RESULT CODE erhalten?Sie können jeden Teil des Codes ändern.

War es hilfreich?

Lösung

Ich habe alle vorherigen EDITs entfernt, da sie nicht mehr relevant sind. Sie können sie im EDIT-Verlauf nachlesen.
BEARBEITEN3
Grundsätzlich besteht das Problem darin, dass Sie den Selektor nicht zwischenspeichern können.Das liegt daran, dass die Funktion $() übereinstimmende Objekte zurückgibt, keine nicht übereinstimmenden Objekte.Das bedeutet, dass die Verwendung eines zwischengespeicherten Selektors dazu führen kann, dass der Cache nicht mehr mit dem echten DOM synchronisiert ist.D.h.auf dieser einfachen Seite:

<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>

Sie müssen die Auswahl also jedes Mal neu treffen, grundsätzlich haben Sie hier zwei Möglichkeiten:

//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)');
  });
}

Welcher schneller ist, sollte man selbst ausprobieren.Ich glaube nicht, dass es eine andere Möglichkeit gibt, sicherzustellen, dass Sie nicht in der Div #do-not-modify-me suchen.

Etwas anderes, was Sie tun könnten, um dies noch einfacher (und meiner Meinung nach schneller) zu machen, wäre, den bearbeitbaren Bereich in ein Div einzuschließen:

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

Dann können Sie es einfach tun

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

Andere Tipps

Sie haben gesagt, der Code kann in keiner Weise verändert werden, nicht wahr? Warum nicht nur daran zu denken, wie das, was Sie tun wollen, anstatt suchen, was Sie nicht suchen möchten. Setzen Sie den Rest des Codes in einem <div> und nur verwenden, die als Rahmen. Es wird keine Eleganz Auszeichnungen gewinnen, aber es ist einfach und erhält die Arbeit erledigt TM .

Ich bin mir ziemlich sicher, dass Sie nur ‚Kontext‘ direkt verwenden können, etwa so:

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

Nach der erweiterten Erklärung lesen werde ich meinen Schuss versuchen:

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

Sie können sogar tun:

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

Um Anzahl von Element erhalten Sie tun können:

var len = context.length;

Für den Zugriff auf Elementnummer i in der Sammlung, die Sie verwenden können:

context.get(i);

Und es gibt jede Menge nützliche Informationen über api.jquery.com , lesen Sie auch diese wahrscheinlich werden Sie Ihre eigenen Wähler erstellen.

EDIT:
Nach dem, sah ich meine Update Ich denke, was für Sie suchen Fähigkeit Iterierte ist über Context-Elemente ergibt, so könnte es geschehen, wie ich hier einige Zeit erwähnt habe durch:

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

Dies sieht nicht so clever, aber funktionieren sollte, können Sie diese .FN und Funktion für Ihre Zwecke der Umsetzung $ durch die Erweiterung einkapseln können.      EDIT # 2:     
    Lassen Sie uns versuchen, einen anderen Weg:

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

})(jQuery);

Danach können Sie tun contex.pick ( „p“), so wird es zurückkehren Sie alle Absatz in Ihrem Ergebnismenge, aber dieser Code ist unvollständig, so dass Sie einige mehr in jquery Code suchen müssen, zum Beispiel zu implementieren es in einer Art und Weise in der Lage, Ihnen die vollständige jquery Funktionalität mit Pick Funktion zu nutzen, müssen Sie wahrscheinlich zu verwenden, zu prüfen, XPath-DOM-Parser .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top