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

Разбор строки html с использованием jquery

Я пытаюсь разобрать этот html через jQuery, чтобы получить data1, data2, data3. Пока я получаю data2 и data3, я не могу получить data3 с моим подходом. Я новичок в jQuery, поэтому, пожалуйста, простите мое невежество.

<html>
<body>
   <div class="class0">
    <h4>data1</h4>
    <p class="class1">data2</p>
    <div id="mydivid"><p>data3</p></div>    
   </div>
</body>
</html>

Вот как я называю это в своем jquery.

var datahtml = "<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>";

alert($(datahtml).find(".class0").text()); // Doesn't Work

alert($(datahtml).find(".class1").text()); // work 

alert($(datahtml).find("#mydivid").text()); // work

Только alert($(datahtml).find(".class0").text()); не работает, остальные работают как ожидалось. Мне интересно, может быть, потому, что class0 имеет несколько тегов внутри него или что? Как получить данные1 в таком сценарии?

4b9b3361

Ответ 1

Его поведение является странным, поскольку оно igonores тега html и body и начинается с первого div с классом = "class0". Html анализируется как элементы DOM, но не добавляется в DOM. Для элементов, добавленных в DOM, селектор не игнорирует тег тела и применяет селектора в документе. Вам нужно добавить html в DOM, как показано ниже.

Живая демонстрация

$('#div1').append($(datahtml)); //Add in DOM before applying jquery methods.

alert($('#div1').find(".class0").text()); // Now it Works too

alert($('#div1').find(".class1").text()); // work   

alert($('#div1').find("#mydivid").text()); // work

Если мы обернем ваш html в некоторый элемент html, чтобы сделать его отправной точкой вместо вашего первого div с class= "class0", тогда ваш селектор будет работать как ожидалось.

Живая демонстрация

var datahtml = "<html><body><div><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></div></body></html>";

alert($(datahtml).find(".class0").text()); // Now it Works too

alert($(datahtml).find(".class1").text()); // work   

alert($(datahtml).find("#mydivid").text()); // work

Что jQuery сообщает о функции разбора jQuery jQuery() i.e. $()

При передаче сложного HTML некоторые браузеры не могут генерировать DOM что точно реплицирует предоставленный HTML-источник. Как уже упоминалось, jQuery использует свойство .innerHTML браузера для анализа прошедших HTML и вставьте его в текущий документ. Во время этого процесса некоторые браузеры отфильтровывают определенные элементы, такие как <html>, <title> или <head> элементов. В результате вставленные элементы могут не быть представитель исходной строки.

Ответ 2

Ни один из текущих ответов не затронул реальную проблему, поэтому я отдам ей это.

var datahtml = "<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>";

console.log($(datahtml));

$(datahtml) - объект jQuery, содержащий только элемент div.class0, поэтому, когда вы вызываете .find на нем, вы фактически ищете потомков div.class0 вместо всего HTML-документа, который вы ожидаете.

Быстрое решение состоит в том, чтобы обернуть анализируемые данные в элементе, чтобы .find работал по назначению:

var parsed = $('<div/>').append(datahtml);
console.log(parsed.find(".class0").text());

Fiddle


Причина этого не очень проста, но я предполагаю, что поскольку jQuery выполняет "синтаксический анализ" более сложных строк html, просто отбрасывая вашу HTML-строку в отдельный созданный на месте фрагмент DOM, а затем извлекает анализируемые элементы, эта операция, скорее всего, заставит DOM-парсер игнорировать теги html и body, поскольку в этом случае они были бы незаконными.

Вот очень маленький набор тестов, который демонстрирует, что это поведение согласовано с помощью jQuery 1.8.2 вплоть до 1.6.4.

Изменить:, цитируя этот пост:

Проблема в том, что jQuery создает DIV и устанавливает innerHTML, а затем принимает DIV, но поскольку элементы BODY и HEAD недействительны DIV childs, то они не создаются браузером.

Я уверен, что моя теория верна. Я расскажу об этом здесь, надеюсь, это будет иметь для вас смысл. Имейте jQuery 1.8.2 несжатый источник рядом с этим. # указывает номера строк.

Все фрагменты документа, сделанные с помощью jQuery.buildFragment (определенные @# 6122), пройдут через jQuery.clean (# 6151) (даже если это кешированный фрагмент, он уже прошел через jQuery.clean, когда он был создан), и, как следует из приведенного выше цитированного текста, jQuery.clean (определенный @# 6275) создает свежий div внутри безопасного фрагмента, который служит контейнером для проанализированных данных - div, созданный на # 6301-6303, childNodes, извлеченный на # 6344, div удален на # 6347 для очистки (плюС# 6359-6361 как исправление ошибок), childNodes, объединенный в возвращаемый массив на # 6351- 6355 и вернулся на # 6406.

Следовательно, все методы, которые вызывают jQuery.buildFragment, которые включают jQuery.parseHTML и jQuery.fn.domManip, среди них: .append(), .after(), .before(), которые вызывают метод объекта domManip jQuery, а $(html), который обрабатывается в jQuery.fn.init (определенный @# 97, обработка сложного [более одного тега] html строк @# 125, вызывает jQuery.parseHTML @# 131).

Имеет смысл, что практически все синтаксические строки jQuery HTML (помимо одиночных строк HTML-тегов) выполняются с использованием элемента div в качестве контейнера, а теги html/body являются недопустимыми потомками элемента div поэтому они лишены.


Добавление: Новые версии jQuery (1.9+) реорганизовали логику синтаксического анализа HTML (например, внутренний метод jQuery.clean больше не существует), но общая логика синтаксического анализа остается той же.

Ответ 3

Я думаю, что у меня есть еще лучший способ:

скажем, у вас есть html:

var htmlText = '<html><body><div class="class0"><h4>data1</h4><p class="class1">data2</p><div id="mydivid"><p>data3</p></div></div></body></html>'

Вот то, что вы надеялись сделать:

var dataHtml = $($.parseXML(htmlText)).children('html');

dataHtml теперь работает точно так же, как обычные объекты jquery, с которыми вы знакомы!!

Замечательная вещь в этом решении заключается в том, что он не будет разделять теги тела, головы или script!

Ответ 4

Попробуйте это

alert($(datahtml).find(".class0 h4").text());

Причина того, что текст, на который вы ссылаетесь, находится внутри элемента h4 class0. Поэтому ваш селектор не будет работать, Или напрямую обращайтесь к содержимому.

alert($(".class0 h4").text()); 

alert($(".class1").text()); 

alert($("#mydivid").text()); 

ИЗМЕНИТЬ

var datahtml = "<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>";

$('body').html(datahtml);

   alert($(".class0 h4").text()); 

    alert($(".class1").text()); 

    alert($("#mydivid").text()); 

ПРОВЕРИТЬ ДЕМО

Ответ 5

Я не знаю другого способа, чем размещение HTML во временном невидимом контейнере.

$(document).ready(function(){
  var datahtml = $("<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>".replace("\\", ""));
  var tempContainer = $('<div style="display:none;">'+ datahtml +'</div>');
  $('body').append(tempContainer);
  alert($(tempContainer).find('.class1').text());
  $(tempContainer).remove();                                                                                                                                                        
});
​

Вот jsfiddle demo.

Ответ 6

Это не работает, потому что <div> с классом class0 не имеет текстовых узлов в качестве прямых дочерних элементов. Добавьте класс в <h4> и он будет работать

Ответ 7

Я думаю, главная проблема заключается в том, что вы не можете использовать html для jQuery. В вашем случае, что происходит с Jquery, так это то, что он пытается найти первый тег html, который в вашем случае является div с классом0.

Проверьте это, чтобы убедиться, что я прав:

if($(datahtml).hasClass('class0'))
    alert('Yes you are right :-)');

Таким образом, это означает, что вы не можете добавить тег html и body в качестве части для запроса.

Если вы хотите заставить его работать, попробуйте добавить эту часть кода:

<div>
    <div class="class0">
        <h4>data1</h4>
        <p class="class1">data2</p>
        <div id="mydivid"><p>data3</p></div>    
   </div>
</div>

Итак, попробуйте следующее:

var datahtml = "<div><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></div>";

alert($(datahtml).find(".class0").text()); // work

alert($(datahtml).find(".class1").text()); // work 

alert($(datahtml).find("#mydivid").text()); // work