После внедрения html кэшированный селектор jQuery дает результат, отличный от не кэшированного селектора.
Нашел решение! Не беспокойтесь, создавая ответ
Оказывается, я вводил html дважды - один раз перед созданием селекторов, а затем, из-за незавершенного рефакторинга, второй раз; перезаписывая соответствующие части DOM. Кэшированные селекторы все еще ссылались на старую часть DOM, поэтому не позволяли собирать мусор. Изменение старой части, конечно, не повлияло на новые части, что было наглядно продемонстрировано, когда jQuery сделал выбор заново.
Вопрос
Я пытаюсь создать виджет. После запуска своего скрипта виджет находит определенный код с тегом (ниже обозначается как $rootElem), загружает фрагмент HTML-кода и вставляет его в этот div. После этого он начинает прикреплять события к элементам ввода, создавать элементы пользовательского интерфейса, такие как ползунки и т. Д.
AFAIK, после внедрения html в DOM, полученный DOM должен быть эквивалентен наличию html там для начала. Оказывается, что JQuery думает иначе. Просто чтобы быть точным, я сначала внедряю HTML, а второй начинаю находить и кэшировать результаты селектора.
Следующие кодовые блоки должны быть эквивалентны (делать то же самое); изменить кусок HTML, как <span>awaiting calculation ...</span>
в нечто вроде <span>1234</span>
, И, о чудо, если я помещу все HTML в один и тот же документ (не вставляя его), они фактически делают одно и то же.
Кэширование результата селектора для последующего поиска
var $result = $rootElem.find( "div.result p:nth-of-type(1) span" );
$.subscribe( "/server/calculateLoan/finished", function ( e, firstPayment ) {
$result.text( firstPayment ) );
} );
Делая выбор каждый раз
$.subscribe( "/server/calculateLoan/finished", function ( e, firstPayment ) {
$rootElem.find( "div.result p:nth-of-type(1) span" ).text( firstPayment ) );
} );
Но если я уберу html-код виджета из основного документа и вставлю его перед началом работы с ним, будет работать только не кэшированная (последняя) версия. На самом деле первый тоже работает. Если я установлю точку останова в анонимной функции, я смогу увидеть странную вещь:
> $result.text()
<span>awaiting calculation ...</span>
> $rootElem.find( "div.result p:nth-of-type(1) span" ).text()
<span>awaiting calculation ...</span>
> $result.text("1234") //This is not showing in the browser window!
[<span>1234</span>]
> $result.text() //This is not showing in the browser window!
[<span>1234</span>]
> $($result.selector).text() //What kind of magic is this?!
<span>awaiting calculation ...</span>
> $rootElem.find( "div.result p:nth-of-type(1) span" ).text()
<span>awaiting calculation ...</span>
Кажется, что кэшированный селектор jQuery указывает на другой элемент DOM (изменения которого не показаны), чем если бы я искал тот же элемент. И это происходит только при внедрении html, а не когда html виджета был вставлен на страницу. Кто-нибудь хочет объяснить, что происходит?
Это происходит как в Chrome, так и в Firefox.
HTML-бит на главной странице выглядит следующим образом:
<div id="widget_calculator"><!-- dynamic fetch --> </div>
HTML виджета
<h1>Widget calculator</h1>
<div class="user-inputs">...</div>
<div class="result">
<p><span>awaiting calculation ...</span></p>
</div>
Код, который внедряет HTML
function fetchHtmlTemplate( templateUrl ) {
// set globals
$ = jQuery;
$rootElem = $( "#widget_calculator" );
$.get( templateUrl, function ( htmlTemplate ) {
$rootElem.html( htmlTemplate );
buildWidget();
} );
}