Получить выделенный элемент внешнего HTML
Я пытаюсь получить HTML-код выбранного объекта с помощью jQuery. Я знаю функцию .html()
; проблема в том, что мне нужен HTML, включая выбранный объект (строка таблицы в этом случае, где .html()
возвращает только ячейки внутри строки).
Я обыскал и нашел несколько очень "хакерских" методов клонирования объекта, добавив его к вновь созданному div и т.д. и т.д., но это кажется действительно грязным. Есть ли лучший способ, или новая версия jQuery (1.4.2) предлагает любые функции outerHtml
?
Ответы
Ответ 1
2014 Edit: вопрос и этот ответ с 2010 года. В то время не было лучшего решения. Теперь многие другие ответы лучше: Эрик Ху, или Ре Капча, например.
У этого сайта есть решение для вас:
jQuery: outerHTML | Yelotofu
jQuery.fn.outerHTML = function(s) {
return s
? this.before(s).remove()
: jQuery("<p>").append(this.eq(0).clone()).html();
};
Ответ 2
Я считаю, что в настоящее время (5/1/2012) все основные браузеры поддерживают функцию externalHTML. Мне кажется, что этого фрагмента достаточно. Я бы лично запомнил это:
// Gives you the DOM element without the outside wrapper you want
$('.classSelector').html()
// Gives you the outside wrapper as well only for the first element
$('.classSelector')[0].outerHTML
// Gives you the outer HTML for all the selected elements
var html = '';
$('.classSelector').each(function () {
html += this.outerHTML;
});
//Or if you need a one liner for the previous code
$('.classSelector').get().map(function(v){return v.outerHTML}).join('');
РЕДАКТИРОВАТЬ: Основная статистика поддержки для element.outerHTML
Ответ 3
Нет необходимости генерировать для него функцию. Просто сделайте это так:
$('a').each(function(){
var s = $(this).clone().wrap('<p>').parent().html();
console.log(s);
});
(Кстати, ваша консоль браузера покажет, что регистрируется. Большинство последних браузеров с 2009 года имеют эту функцию.)
Магия в конце:
.clone().wrap('<p>').parent().html();
Клон означает, что вы фактически не нарушаете DOM. Запустите его без него, и вы увидите теги p
, вставленные до/после всех гиперссылок (в этом примере), что нежелательно. Итак, да, используйте .clone()
.
Как он работает, так это то, что он принимает каждый тэг a
, делает его клоном в ОЗУ, обертывает тегами p
, получает родительский элемент (что означает тег p
), а затем получает innerHTML
его свойство.
РЕДАКТИРОВАТЬ. Принял совет и изменил теги div
на теги p
, потому что он меньше печатает и работает одинаково.
Ответ 4
Как насчет: prop('outerHTML')
?
var outerHTML_text = $('#item-to-be-selected').prop('outerHTML');
И для установки:
$('#item-to-be-selected').prop('outerHTML', outerHTML_text);
Это сработало для меня.
PS: это добавлено в jQuery 1.6.
Ответ 5
Расширить jQuery:
(function($) {
$.fn.outerHTML = function() {
return $(this).clone().wrap('<div></div>').parent().html();
};
})(jQuery);
И используйте его следующим образом: $("#myTableRow").outerHTML();
Ответ 6
Я согласен с Арпаном (Dec 13 '10 5:59).
Его способ сделать это на самом деле намного лучше, если вы не используете клон. Метод clone очень трудоемкий, если у вас есть дочерние элементы, и никто, похоже, не заботился о том, чтобы IE действительно имел атрибут outerHTML
(у IE действительно есть НЕКОТОРЫЕ полезные трюки в рукаве).
Но я бы, вероятно, создал его script немного другим:
$.fn.outerHTML = function() {
var $t = $(this);
if ($t[0].outerHTML !== undefined) {
return $t[0].outerHTML;
} else {
var content = $t.wrap('<div/>').parent().html();
$t.unwrap();
return content;
}
};
Ответ 7
Чтобы быть по-настоящему jQuery-esque, вы можете захотеть outerHTML()
быть геттером и установщиком и как можно более похожим на html()
:
$.fn.outerHTML = function (arg) {
var ret;
// If no items in the collection, return
if (!this.length)
return typeof arg == "undefined" ? this : null;
// Getter overload (no argument passed)
if (!arg) {
return this[0].outerHTML ||
(ret = this.wrap('<div>').parent().html(), this.unwrap(), ret);
}
// Setter overload
$.each(this, function (i, el) {
var fnRet,
pass = el,
inOrOut = el.outerHTML ? "outerHTML" : "innerHTML";
if (!el.outerHTML)
el = $(el).wrap('<div>').parent()[0];
if (jQuery.isFunction(arg)) {
if ((fnRet = arg.call(pass, i, el[inOrOut])) !== false)
el[inOrOut] = fnRet;
}
else
el[inOrOut] = arg;
if (!el.outerHTML)
$(el).children().unwrap();
});
return this;
}
Рабочая демонстрация: http://jsfiddle.net/AndyE/WLKAa/
Это позволяет нам передать аргумент outerHTML
, который может быть
- функция отмены —
function (index, oldOuterHTML) { }
— где возвращаемое значение станет новым HTML для элемента (если не возвращается false
).
- строка, которая будет установлена вместо HTML каждого элемента.
Дополнительную информацию см. в документах jQuery для html()
.
Ответ 8
Вы также можете использовать get (Получить элементы DOM, соответствующие объекту jQuery.).
например:
$('div').get(0).outerHTML;//return "<div></div>"
Как метод расширения:
jQuery.fn.outerHTML = function () {
return this.get().map(function (v) {
return v.outerHTML
}).join()
};
Или же
jQuery.fn.outerHTML = function () {
return $.map(this.get(), function (v) {
return v.outerHTML
}).join()
};
Множественный выбор и возврат внешнего HTML всех найденных элементов.
$('input').outerHTML()
вернуть:
'<input id="input1" type="text"><input id="input2" type="text">'
Ответ 9
Чтобы создать FULL jQuery-плагин как .outerHTML
, добавьте следующий script в любой js файл и включите после jQuery в своем заголовке:
update Новая версия имеет лучший контроль, а также более удобный сервис JQuery Selector!:)
;(function($) {
$.extend({
outerHTML: function() {
var $ele = arguments[0],
args = Array.prototype.slice.call(arguments, 1)
if ($ele && !($ele instanceof jQuery) && (typeof $ele == 'string' || $ele instanceof HTMLCollection || $ele instanceof Array)) $ele = $($ele);
if ($ele.length) {
if ($ele.length == 1) return $ele[0].outerHTML;
else return $.map($("div"), function(ele,i) { return ele.outerHTML; });
}
throw new Error("Invalid Selector");
}
})
$.fn.extend({
outerHTML: function() {
var args = [this];
if (arguments.length) for (x in arguments) args.push(arguments[x]);
return $.outerHTML.apply($, args);
}
});
})(jQuery);
Это позволит вам не только получить outerHTML одного элемента, но даже получить массив сразу нескольких элементов сразу! и может использоваться в обоих стандартных стилях jQuery:
$.outerHTML($("#eleID")); // will return outerHTML of that element and is
// same as
$("#eleID").outerHTML();
// or
$.outerHTML("#eleID");
// or
$.outerHTML(document.getElementById("eleID"));
Для нескольких элементов
$("#firstEle, .someElesByClassname, tag").outerHTML();
Примеры фрагмента:
console.log('$.outerHTML($("#eleID"))'+"\t", $.outerHTML($("#eleID")));
console.log('$("#eleID").outerHTML()'+"\t\t", $("#eleID").outerHTML());
console.log('$("#firstEle, .someElesByClassname, tag").outerHTML()'+"\t", $("#firstEle, .someElesByClassname, tag").outerHTML());
var checkThisOut = $("div").outerHTML();
console.log('var checkThisOut = $("div").outerHTML();'+"\t\t", checkThisOut);
$.each(checkThisOut, function(i, str){ $("div").eq(i).text("My outerHTML Was: " + str); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://rawgit.com/JDMcKinstry/ce699e82c7e07d02bae82e642fb4275f/raw/deabd0663adf0d12f389ddc03786468af4033ad2/jQuery.outerHTML.js"></script>
<div id="eleID">This will</div>
<div id="firstEle">be Replaced</div>
<div class="someElesByClassname">At RunTime</div>
<h3><tag>Open Console to see results</tag></h3>
Ответ 10
вы также можете просто сделать это таким образом
document.getElementById(id).outerHTML
где id - идентификатор элемента, который вы ищете
Ответ 11
Я использовал решение Jessica (которое редактировалось Джошем), чтобы получить outerHTML для работы в Firefox. Однако проблема заключается в том, что мой код прерывается, потому что ее решение завершает элемент в DIV. Добавление еще одной строки кода позволило решить эту проблему.
Следующий код дает вам outerHTML оставляя дерево DOM без изменений.
$jq.fn.outerHTML = function() {
if ($jq(this).attr('outerHTML'))
return $jq(this).attr('outerHTML');
else
{
var content = $jq(this).wrap('<div></div>').parent().html();
$jq(this).unwrap();
return content;
}
}
И используйте его так: $( "# myDiv" ). externalHTML();
Надеюсь, что кто-то сочтет это полезным!
Ответ 12
// no cloning necessary
var x = $('#xxx').wrapAll('<div></div>').parent().html();
alert(x);
Скрипт здесь: http://jsfiddle.net/ezmilhouse/Mv76a/
Ответ 13
Если сценарий добавляет новую строку динамически, вы можете использовать это:
var row = $(".myRow").last().clone();
$(".myRow").last().after(row);
.myrow
- это имя класса <tr>
. Он создает копию последней строки и вставляет ее как новую последнюю строку.
Это также работает в IE7, а метод [0].outerHTML
не позволяет назначать в ie7
Ответ 14
node.cloneNode() вряд ли выглядит как хак. Вы можете клонировать node и добавлять его к любому желаемому родительскому элементу, а также манипулировать им, манипулируя отдельными свойствами, вместо того, чтобы иметь, например, запускать на нем регулярные выражения или добавлять его в DOM, а затем манипулировать им послесловиями.
Тем не менее, вы можете перебирать атрибуты элемента, чтобы построить его строковое представление HTML. Вероятно, именно так будет реализована любая функция outerHTML: jQuery, чтобы добавить ее.
Ответ 15
Вы можете найти хороший вариант .outerHTML() здесь https://github.com/darlesson/jquery-outerhtml.
В отличие от .html(), который возвращает только содержимое элемента HTML, эта версия .outerHTML() возвращает выбранный элемент и его содержимое HTML или заменяет его как метод .replaceWith(), но с той разницей, которая позволяет заменить HTML на наследовать цепочкой.
Примеры также можно увидеть в URL-адресе выше.
Ответ 16
Я использовал решение Volomike, обновленное Jessica. Просто добавлена проверка, чтобы увидеть, существует ли элемент, и заставлял его возвращать пустой, если он этого не делает.
jQuery.fn.outerHTML = function() {
return $(this).length > 0 ? $(this).clone().wrap('<div />').parent().html() : '';
};
Конечно, используйте его как:
$('table#buttons').outerHTML();
Ответ 17
Обратите внимание, что решение Josh работает только для одного элемента.
Возможно, "внешний" HTML действительно имеет смысл, когда у вас есть один элемент, но бывают ситуации, когда имеет смысл взять список элементов HTML и превратить их в разметку.
Расширение решения Josh, оно будет обрабатывать несколько элементов:
(function($) {
$.fn.outerHTML = function() {
var $this = $(this);
if ($this.length>1)
return $.map($this, function(el){ return $(el).outerHTML(); }).join('');
return $this.clone().wrap('<div/>').parent().html();
}
})(jQuery);
Изменить: еще одна проблема с исправлением Josh исправлена, см. комментарий выше.
Ответ 18
Аналогичное решение с добавлением remove()
временного объекта DOM.
Ответ 19
Я сделал этот простой тест с outerHTML, являющимся решением tokimon (без клона), а внешнийHTML2 - решением jessica (clone)
console.time("outerHTML");
for(i=0;i<1000;i++)
{
var html = $("<span style='padding:50px; margin:50px; display:block'><input type='text' title='test' /></span>").outerHTML();
}
console.timeEnd("outerHTML");
console.time("outerHTML2");
for(i=0;i<1000;i++)
{
var html = $("<span style='padding:50px; margin:50px; display:block'><input type='text' title='test' /></span>").outerHTML2();
}
console.timeEnd("outerHTML2");
а результат в моем браузере Chrome (версия 20.0.1132.57 (0)) был
outerHTML: 81ms
externalHTML2: 439ms
но если мы используем решение tokimon без встроенной функции outerHTML (которая теперь поддерживается, вероятно, почти в каждом браузере)
получаем
outerHTML: 594ms
externalHTML2: 332ms
и в реальных примерах будет больше циклов и элементов, поэтому идеальная комбинация будет
$.fn.outerHTML = function()
{
$t = $(this);
if( "outerHTML" in $t[0] ) return $t[0].outerHTML;
else return $t.clone().wrap('<p>').parent().html();
}
поэтому метод clone на самом деле быстрее, чем метод обертывания/разворота
(jquery 1.7.2)
Ответ 20
Вот очень оптимизированный плагин outerHTML для jquery:
(http://jsperf.com/outerhtml-vs-jquery-clone-hack/5 = > 2 быстрых фрагмента кода не совместимы с некоторыми браузерами, такими как FF < 11)
(function($) {
var DIV = document.createElement("div"),
outerHTML;
if ('outerHTML' in DIV) {
outerHTML = function(node) {
return node.outerHTML;
};
} else {
outerHTML = function(node) {
var div = DIV.cloneNode();
div.appendChild(node.cloneNode(true));
return div.innerHTML;
};
}
$.fn.outerHTML = function() {
return this.length ? outerHTML(this[0]) : void(0);
};
})(jQuery);
@Andy E = > Я не согласен с тобой. externalHMTL не нужен getter И сеттер: jQuery уже дает нам "replaceWith"...
@mindplay = > Почему вы присоединяетесь ко всем outerHTML? jquery.html возвращает только содержимое HTML элемента FIRST.
(Извините, у вас недостаточно репутации, чтобы писать комментарии)
Ответ 21
Короткий и сладкий.
[].reduce($('.x'), function(i,v) {return i+v.outerHTML}, '')
или событие более сладкое с помощью функций стрелок
[].reduce.call($('.x'), (i,v) => i+v.outerHTML, '')
или без jQuery вообще
[].reduce.call(document.querySelectorAll('.x'), (i,v) => i+v.outerHTML, '')
или если вам не нравится этот подход, убедитесь, что
$('.x').get().reduce((i,v) => i+v.outerHTML, '')
Ответ 22
Это довольно просто с ванильным JavaScript...
document.querySelector('#selector')
Ответ 23
Это отлично подходит для изменения элементов в dom, но не работает, т.е. при передаче в html-строку в jquery следующим образом:
$('<div id="foo">Some <span id="blog">content</span></div>').find('#blog').outerHTML();
После некоторых манипуляций я создал функцию, которая позволяет выше работать, т.е. для html-строк:
$.fn.htmlStringOuterHTML = function() {
this.parent().find(this).wrap('<div/>');
return this.parent().html();
};
Ответ 24
$.html = el => $("<div>"+el+"</div>").html().trim();
Ответ 25
Я наткнулся на это, ища ответ на мою проблему, которая заключалась в том, что я пытался удалить строку таблицы, а затем добавить ее обратно в нижней части таблицы (поскольку я динамически создавал строки данных, но хотел показать Строка типа "Добавить новую запись" внизу).
У меня была та же проблема, что он возвращал innerHtml, так что отсутствовали теги TR, в которых содержался идентификатор этой строки, и это означало невозможность повторить процедуру.
Ответ, который я нашел, состоял в том, что функция jquery remove()
фактически возвращает элемент, который он удаляет, как объект. Итак, чтобы удалить и снова добавить строку, это было так просто, как это...
var a = $("#trRowToRemove").remove();
$('#tblMyTable').append(a);
Если вы не удаляете объект, но хотите его скопировать в другое место, используйте вместо него функцию clone()
.
Ответ 26
Все, кто ищет простое решение.
просто используйте внешний JavaScript-атрибут JavaScript
$('#elementSelector').get(0).outerHTML
Ответ 27
Плагин jQuery как сокращение для прямого получения всего элемента HTML:
jQuery.fn.outerHTML = function () {
return jQuery('<div />').append(this.eq(0).clone()).html();
};
И используйте это так: $(".element").outerHTML();
Ответ 28
$("#myNode").parent(x).html();
Где 'x' - это номер node, начиная с 0 в качестве первого, должен получить нужную node, если вы хотите получить конкретную. Если у вас есть дочерние узлы, вы действительно должны поместить идентификатор в тот, который вам нужен, но на нулевом уровне. Использование этой методологии и "х" отлично работало для меня.
Ответ 29
Простое решение.
var myself = $('#div').children().parent();
Ответ 30
$("#myTable").parent().html();
Возможно, я не правильно понимаю ваш вопрос, но это приведет к отображению элемента html выбранного элемента.
Это то, что тебе нужно?