Подтвердить что ты не робот

JQuery() не находит элементы в результате jQuery.parseHTML()

Я пишу тесты с помощью QUnit и используя $.ajax(), чтобы вытащить HTML для некоторых тестов из сайта dev, работающего на моем локальном:

add_elements = function(location, selector) { 
  $.ajax(location, {async: false}).done(function(data) {
    stor.$els = $(selector, $.parseHTML(data));
    stor.$els.appendTo($('body'));
  })
}

Используя эту функцию в определенном месте, я получаю следующий data, переданный моему обратному сообщению .done():

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Home</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="/static/css/bootstrap.min.css" rel="stylesheet" media="screen">

</head>

<body>
<div id="app-container" class="container-fluid">
    <div class="page-header">
        <h1>
            <a href="/">Home</a>
            <small>Text</small>
        </h1>
    </div>

    <div id="hero-units" class="carousel-inner slide">

        <div class="hero-unit home item active">
            <h1>
                Text text text
            </h1>
            <p>
                More text!
            </p>
            <div id="app-nav">
                <a id="lets-go" class="btn btn-primary btn-large nav-forward" href="/what-up/">
                    Let go
                </a>
            </div>
        </div>

    </div>
</div>

<script src="/static/js/jquery.js"></script>
<script src="/static/js/underscore.js"></script>
<script src="/static/js/backbone.js"></script>
<script src="/static/js/bootstrap.js"></script>
<script src="/static/js/site-fiddle.js"></script>
<script src="/static/js/site.js"></script>

</body>
</html>

Все работает, если selector равно #hero-units или .hero-unit, но $(selector, $.parseHTML(data)) ничего не возвращает, если selector is #app-container! И я хочу объект jQuery для элемента div#app-container.

И вот что меня убило:

  • $.parseHTML(data) содержит элемент div#app-container. Это просто $.parseHTML(data)[7].
  • Тем не менее, $('#app-container', $.parseHTML(data)) - пустой массив.
  • $('div', $.parseHTML(data)) содержит все div внутри div#app-container, но не div#app-container.

Что здесь происходит? Похоже, что происходит то, что $ не смотрит ни на один из элементов верхнего уровня, возвращаемых $.parseHTML(data) или $($.parseHTML(data))), и просто их дочерние элементы.

Как я могу получить объект jQuery для div#app-container из этого $.parseHTML(data)?

ANSWER

Поиск $(selector, $.parseHTML(data)) -style использует $.find. Поскольку я ищу элемент верхнего уровня в этом объекте jQuery, вместо этого я должен использовать $.filter. Вуаля.

4b9b3361

Ответ 1

Вам нужно создать элемент DOM, чтобы сначала добавить результаты .parseHTML(), чтобы он создал дерево DOM, прежде чем jQuery сможет пересечь его и найти div#app-container.

var tempDom = $('<output>').append($.parseHTML(str));
var appContainer = $('#app-container', tempDom);

Я использовал ваш пример и получил его работу: http://jsfiddle.net/gEYgZ/

Функция .parseHTML(), кажется, задыхается от тегов <script>, поэтому мне пришлось удалить их.

PS. Очевидно, что <output> не является реальным тегом HTML, просто используя его для примера

Ответ 2

Вы можете попробовать следующее:

$($.parseHTML('<div><span id="foo">hello</span></div>')).find('#foo');

для строк, начинающихся с <, вы можете сократить этот код:

$('<div><span id="foo">hello</span></div>').find('#foo');

Ответ 3

Просто наткнулся на это.

Выключает $.parseHTML возвращает vanilla Array из DOM-элементов и не поддерживает поиск jQuery, которое вы хотите.

Я думаю, что это самое чистое решение для преобразования строки HTML в объект jQuery:

var html = '<div><span id="foo">hello</span></div>';
var $foo = $(html).find('#foo');

Примечание. Вы можете использовать $.trim вокруг своих строк html, чтобы jQuery не путался пробелами.

Ответ 4

Это не имеет ничего общего с HTML, не являющимся частью DOM. Просто по какой-то причине теги верхнего уровня в разобранном HTML не могут быть найдены. Если искомый элемент обернут в другой тег, то поиск работает так, как вы ожидаете. Кстати, обертывание элемента в теге body не сработает, но все остальные, которые я пробовал, работают нормально.

var bad = $.parseHTML('<ul><<li><one/li>/<li>two</li></ul>');
console.log($(bad).find('li').length);  //will be 2
console.log($(bad).find('ul').length);  //will be 0 

var good = $.parseHTML('<div><ul><<li><one/li>/<li>two</li></ul></div>');
console.log($(good).find('li').length); //will be 2
console.log($(good).find('ul').length); //will be 1

Это определенно имеет место в jQuery 1.11, не уверен, что произойдет в более поздних версиях. Вот скрипка, которая демонстрирует: http://jsfiddle.net/ndnnhf94/

Ответ 5

Я думаю, вам стоит попробовать:

$('body', $.parseHTML(data))

Ответ 6

Я считаю, что это сработает, особенно если вам нужно найти элемент по id;

function findInParsed(html, selector){
    return $(selector, html).get(0) || $(html).filter(selector).get(0);
}

Если вам нужна версия jquery для объекта, вы можете получить ее с помощью этого

function findInParsed(html, selector){
    var check = $(selector, html).get(0);
    if(check)
        return $(check);
    check = $(html).filter(selector).get(0)
    return (check)? $(check) : false;
}

Ответ 7

Приведенные выше ответы не спомогли мне, это сработало:

используйте jQuery.parseHTML, чтобы разобрать HTML в массив элементов; тогда вы сможете преобразовать его в коллекцию jQuery и использовать фильтр, чтобы ограничить коллекцию элементами, соответствующими селектору.

var html =
'<td class="test">asd</td>' +
'<td class="last">jkl</td>';
var obj = $($.parseHTML(html)).filter('.test');