gpt4 book ai didi

javascript - 使用 .cloneContents() 时如何防止标签自动关闭

转载 作者:行者123 更新时间:2023-12-05 06:13:57 25 4
gpt4 key购买 nike

上下文

我正在尝试根据文本本身获取所选文本的 HTML。因此,如果将以下 HTML 实现到页面中:

<p>Random content <span>here and other</span> random content here.</p>

它会像这样显示:

Random content here and other random content here.

如果用户选择content here and ,我不仅要获取文本,还要获取周围的 HTML。我发现了以下功能,它可以有效地做到这一点:

function getSelectionHtml() {

var html = "";

if (typeof window.getSelection != "undefined") {

var sel = window.getSelection();

if (sel.rangeCount) {

var container = document.createElement("div");

for (var i = 0, len = sel.rangeCount; i < len; ++i) {

container.appendChild(sel.getRangeAt(i).cloneContents());

}

html = container.innerHTML;
}

} else if (typeof document.selection != "undefined") {

if (document.selection.type == "Text") {

html = document.selection.createRange().htmlText;

}

}

return html;

}

结果将是 content <span>here and </span> .唯一的问题是 <span>标签会自动关闭,即使我没有选择超过结束 span 标签的文本。查看 .cloneContents() 的 MDN 文档时,它说:

Partially selected nodes include the parent tags necessary to make the document fragment valid.

我相信这可以解释为什么标签会自行关闭。

问题

如何在没有结束标记的情况下获取所选文本及其 HTML(除非我也选择它)?在这种情况下,如何获取文本 content <span> here and而不是 content <span>here and </span> ?不过,如果我要选择跨度包含的整个语句,我希望它被包括在内。

我尝试过的事情

我试着切断 </span>在字符串的末尾(如果它存在)具有以下功能,但当我跨越多个 HTML 标记时它会崩溃。我想要 span , strong , 和 i如果我不突出显示它们包含的所有文本,标签将被切断。因此,当跨越一个元素时,它会起作用,但当你跨越多个元素时,它就不起作用了。即使我将鼠标悬停在跨度包含的整个文本上,它也会切断跨度,因此此解决方案不起作用。

$("p").click(function() {

if (window.getSelection) {

sel = window.getSelection();

} else if (document.selection && document.selection.type != "Control") { //for IE

sel = document.selection.createRange();

}

var selectedText = getSelectionHTML();

checkTags(selectedText);

});

function checkTags(selectedText) {

var prohibited = ['</span>', '</strong>', '</i>'];

for (var i = 0; i < prohibited.length; i++) {

if (selectedText.indexOf(prohibited[i]) > -1) {

var splitText = selectedText.split("</");
splitText.pop();

}

}

alert(splitText);

}

function getSelectionHTML() {

var html = "";

if (typeof window.getSelection != "undefined") {

var sel = window.getSelection();

if (sel.rangeCount) {

var container = document.createElement("div");

for (var i = 0, len = sel.rangeCount; i < len; ++i) {

container.appendChild(sel.getRangeAt(i).cloneContents());

}

html = container.innerHTML;
}

} else if (typeof document.selection != "undefined") {

if (document.selection.type == "Text") {

html = document.selection.createRange().htmlText;

}

}

return html;

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>This random content is here <span> within the span <span> <strong>other random content</strong> is here.</p>

最佳答案

我发现您的问题非常有趣,并进行了一些修改。通过您展示的 slim 示例,一切似乎都有效。但是,我不能给予 100% 的保证,因为需要证明的案例太多了。但我希望我能举例说明如何解决这个问题。

也许你试试我创建的插件,然后告诉我它是否有效。您可以在 jsFiddle 上找到 fiddle 以及以下代码的第一个版本:

$.fn.selection = function(options) {

var $el = this,
lastSelections = [],
$settings = $.extend({}, $.fn.selection.defaults, options);

function removeCloseTags(range, selectionText) {
if (range.endOffset < range.endContainer.length) {
selectionText = selectionText.replace(
new RegExp('<\/' + range.endContainer.parentElement.localName + '>(<\/[a-z]+>)*', 'gm'),
''
);
} else {
var sibling = range.startContainer.nextSibling;

if (sibling != null) {
var siblingName = sibling.localName,
contents = new RegExp('<' + siblingName + '>(.*)<\/' + siblingName + '>', 'gm').exec(selectionText);

if (contents != null && typeof contents[1] != 'undefined' && sibling.innerHTML != contents[1]) {
selectionText = selectionText.replace(
new RegExp('<\/' + siblingName + '>(<\/[a-z]+>)*', 'gm'),
''
);
}
}
}

return selectionText;
}

function removeOpenTags(element, selectionText) {
var sibling = element.parentElement;

if (selectionText.indexOf(sibling.innerHTML) != 0) {
selectionText = selectionText.replace(
new RegExp('^(<[a-z]+>)*<' + sibling.localName + '>', 'gm'),
''
);
}

return selectionText;
}

function getSelectionText(container, selection, range) {
var selectionText = container.innerHTML;

container.innerHTML = '';
container.appendChild(range.cloneContents());
selectionText = container.innerHTML;

if ($settings.removeCloseTags) {
selectionText = removeCloseTags(range, selectionText);
}

if ($settings.removeOpenTags) {
selectionText = removeOpenTags(range.startContainer, selectionText, 0);
}

return selectionText;
}

function getSelections() {
lastSelections = [];

if (typeof window.getSelection != 'undefined') {
var selection = window.getSelection(),
container = document.createElement('div');

if (!selection.isCollapsed && selection.rangeCount) {
var selectionRangeCount = selection.rangeCount;

for (var i = 0; i < selectionRangeCount; ++i) {
lastSelections.push(getSelectionText(container, selection, selection.getRangeAt(i)));
}
}
}

$settings.onSelection.call($el, lastSelections);
return lastSelections;
}

var onMouseUp = function(event) {
$settings.onMouseUp.call($el, event);
getSelections();
};

var onSelectionChange = function(event) {
$settings.onSelectionChange.call($el, event);
getSelections();
};

$el.getLastSelections = function() {
return lastSelections;
};

$el.on('mouseup', onMouseUp);
$(document).on('selectionchange', onSelectionChange);

var init = function() {
return $el;
};

return init();

};

$.fn.selection.defaults = {
removeCloseTags: true,
removeOpenTags: true,
onMouseUp: function(event) {},
onSelectionChange: function(event) {},
onSelection: function(selections) {},
};

$(document).ready(function() {
var selection = $('body').selection({
onSelection: function(selections) {
var selectionString = selections.join()
.replace(new RegExp('<', 'gm'), '&lt;')
.replace(new RegExp('>', 'gm'), '&gt;');

$('pre').html(selectionString);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p>Random content <span>here <i>and</i> other</span> random content here.</p>
<p>This random content is here <span> within the span </span> <strong>other random content</strong> is here.</p>

<pre></pre>

关于javascript - 使用 .cloneContents() 时如何防止标签自动关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63113811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com