Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS:获取contentEditable div中所有选定节点的数组_Javascript_Html_Wysiwyg - Fatal编程技术网

Javascript JS:获取contentEditable div中所有选定节点的数组

Javascript JS:获取contentEditable div中所有选定节点的数组,javascript,html,wysiwyg,Javascript,Html,Wysiwyg,嗨,我已经和contentEditable合作一段时间了,我想我对它有很好的把握。我回避的一件事是如何获得对部分或完全在用户选择范围内的所有节点的引用数组。有人有主意吗 以下是一些开始: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w

嗨,我已经和contentEditable合作一段时间了,我想我对它有很好的把握。我回避的一件事是如何获得对部分或完全在用户选择范围内的所有节点的引用数组。有人有主意吗

以下是一些开始:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function getSelectedNodes(){
    var sel = window.getSelection();
    try{var frag=sel.getRangeAt(0).cloneContents()}catch(e){return(false);}
    var tempspan = document.createElement("span");
    tempspan.appendChild(frag);

    var selnodes = Array() //<<- how do I fill this array??
    var output = ''
    for(i in selnodes){
        output += "A "+selnodes[i].tagName+" was found\n"
        //do something cool with each element here...
    }
    return(output)
}
</script>
</head>

<body contentEditable="true" onkeypress="return(keypress(event))">
<div>This <strong>div</strong> is <em>content</em> <span class='red'>editable</span> and has a couple of <em><strong>child nodes</strong></em> within it</div>
<br />
<br />
<a href="#" onmouseover="alert(getSelectedNodes())">hover here</a>
</body>
</html>

函数getSelectedNodes(){
var sel=window.getSelection();
请尝试{var frag=sel.getRangeAt(0).cloneContents()}catch(e){return(false);}
var tempspan=document.createElement(“span”);
临时儿童(frag);

var selnodes=Array()//你太接近了!当你将
文档片段
附加到临时
span
元素时,你已经把它们变成了一个可管理的组,可以通过可信的
childNodes
数组访问

    var selnodes = tempspan.childNodes;
此外,您正在设置
for(i in selnodes)
循环,该循环将返回数组中的元素,加上
长度
属性、
\uuuuu proto\uuu
属性以及对象可能具有的任何其他属性

当在对象中的属性上循环时,实际上应该只对
循环使用这些类型的
,然后始终使用
if(obj.hasOwnProperty[i])
来过滤从原型继承的属性

在阵列中循环时,请使用:

    for(var i=0,u=selnodes.length;i<u;i++)
事情是这样的:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function getSelectedNodes(){
    var sel = window.getSelection();
    try{var frag=sel.getRangeAt(0).cloneContents()}catch(e){return(false);}
    var tempspan = document.createElement("span");
    tempspan.appendChild(frag);
    console.log(tempspan);
    window.selnodes = tempspan.childNodes;
    var output = ''
    for(var i=0, u=selnodes.length;i<u;i++){
        if (typeof selnodes[i].tagName !== 'undefined'){
          output += "A "+selnodes[i].tagName+" was found\n"
        }
        else output += "Some text was found: '"+selnodes[i].textContent+"'\n";
        //do something cool with each element here...
    }
    return(output)
}
</script>
</head>

<body contentEditable="true" onkeypress="return(keypress(event))">
<div>This <strong>div</strong> is <em>content</em> <span class='red'>editable</span> and has a couple of <em><strong>child nodes</strong></em> within it</div>
<br />
<br />
<a href="#" onmouseover="alert(getSelectedNodes())">hover here</a>
</body>
</html>

函数getSelectedNodes(){
var sel=window.getSelection();
请尝试{var frag=sel.getRangeAt(0).cloneContents()}catch(e){return(false);}
var tempspan=document.createElement(“span”);
临时儿童(frag);
console.log(tempspan);
window.selnodes=tempspan.childNodes;
变量输出=“”

对于(var i=0,u=selnodes.length;i这里有一个版本,它提供实际选定和部分选定的节点,而不是克隆。或者,您可以使用我的库,它有一个范围对象的
getNodes()
方法,在IE<9中工作

function nextNode(node) {
    if (node.hasChildNodes()) {
        return node.firstChild;
    } else {
        while (node && !node.nextSibling) {
            node = node.parentNode;
        }
        if (!node) {
            return null;
        }
        return node.nextSibling;
    }
}

function getRangeSelectedNodes(range) {
    var node = range.startContainer;
    var endNode = range.endContainer;

    // Special case for a range that is contained within a single node
    if (node == endNode) {
        return [node];
    }

    // Iterate nodes until we hit the end container
    var rangeNodes = [];
    while (node && node != endNode) {
        rangeNodes.push( node = nextNode(node) );
    }

    // Add partially selected nodes at the start of the range
    node = range.startContainer;
    while (node && node != range.commonAncestorContainer) {
        rangeNodes.unshift(node);
        node = node.parentNode;
    }

    return rangeNodes;
}

function getSelectedNodes() {
    if (window.getSelection) {
        var sel = window.getSelection();
        if (!sel.isCollapsed) {
            return getRangeSelectedNodes(sel.getRangeAt(0));
        }
    }
    return [];
}

下面的代码是解决您的问题的示例,下面的代码返回范围内所有选定的节点

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>payam jabbari</title>
<script src="http://code.jquery.com/jquery-2.0.2.min.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function(){
    var startNode = $('p.first').contents().get(0);
var endNode = $('span.second').contents().get(0);
var range = document.createRange();
range.setStart(startNode, 0);
range.setEnd(endNode, 5);
var selection = document.getSelection();
selection.addRange(range);
// below code return all nodes in selection range. this code work in all browser
var nodes = range.cloneContents().querySelectorAll("*");
for(var i=0;i<nodes.length;i++)
{
   alert(nodes[i].innerHTML);
}
});
</script>
</head>

<body>
<div>

<p class="first">Even a week ago, the idea of a Russian military intervention in Ukraine seemed far-fetched if not totally alarmist. But the arrival of Russian troops in Crimea over the weekend has shown that he is not averse to reckless adventures, even ones that offer little gain. In the coming days and weeks</p>

<ol>
    <li>China says military will respond to provocations.</li>
    <li >This Man Has Served 20 <span class="second"> Years—and May Die—in </span> Prison for Marijuana.</li>
    <li>At White House, Israel's Netanyahu pushes back against Obama diplomacy.</li>
</ol>
</div>
</body>
</html>

帕亚姆·贾巴里
$(文档).ready(函数(){
var startNode=$('p.first').contents().get(0);
var endNode=$('span.second').contents().get(0);
var range=document.createRange();
range.setStart(startNode,0);
range.setEnd(endNode,5);
var selection=document.getSelection();
选择。添加范围(范围);
//下面的代码返回选择范围内的所有节点。此代码适用于所有浏览器
var nodes=range.cloneContents().queryselectoral(“*”);

对于(var i=0;i我知道我真的很接近!childNodes真的返回DOM实节点数组吗?我无法获取标准属性来处理数组内容。例如:
selnodes[i]。innerHTML='P:'+selnodes[i].innerHTML
Ah-这是在tempspan中返回节点。如何引用原始节点以更改其内容?@cronoklee您可以访问
范围.commonAncestorContainer
节点并迭代其子节点,直到找到
范围.startContainer
范围.endContainer
。Tim,我该怎么做修改数组中的节点?我想通过使用outerHTML(删除第一个p节点的

和第二个p节点的

)合并两个特定的p节点,但它不起作用。这是amaaazing!!!!!我已经抓到我的头了,因为我必须使用cloneContents(),这会丢失对DOM的引用。这是gold Tim。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>payam jabbari</title>
<script src="http://code.jquery.com/jquery-2.0.2.min.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function(){
    var startNode = $('p.first').contents().get(0);
var endNode = $('span.second').contents().get(0);
var range = document.createRange();
range.setStart(startNode, 0);
range.setEnd(endNode, 5);
var selection = document.getSelection();
selection.addRange(range);
// below code return all nodes in selection range. this code work in all browser
var nodes = range.cloneContents().querySelectorAll("*");
for(var i=0;i<nodes.length;i++)
{
   alert(nodes[i].innerHTML);
}
});
</script>
</head>

<body>
<div>

<p class="first">Even a week ago, the idea of a Russian military intervention in Ukraine seemed far-fetched if not totally alarmist. But the arrival of Russian troops in Crimea over the weekend has shown that he is not averse to reckless adventures, even ones that offer little gain. In the coming days and weeks</p>

<ol>
    <li>China says military will respond to provocations.</li>
    <li >This Man Has Served 20 <span class="second"> Years—and May Die—in </span> Prison for Marijuana.</li>
    <li>At White House, Israel's Netanyahu pushes back against Obama diplomacy.</li>
</ol>
</div>
</body>
</html>