Javascript 获取文本选择中的元素
我希望获得用户选择中包含的所有元素(如DOM 2 ranges/MS TextRanges)Javascript 获取文本选择中的元素,javascript,dom,range,Javascript,Dom,Range,我希望获得用户选择中包含的所有元素(如DOM 2 ranges/MS TextRanges) /**@return{Array.}*/ 函数getSelectedElements(){ var元素=[]; //以某种方式获取用户选择中的元素 返回元素; } 我试着通过跟随Tim Down的优秀作品,一些Moz和MS文档,以及一些PPK的东西来做到这一点 方法基本上是: 将SelectionLikeObject定义为DOM选择或IE选择 将RangeLikeObject定义为DOM范围或IE
/**@return{Array.}*/
函数getSelectedElements(){
var元素=[];
//以某种方式获取用户选择中的元素
返回元素;
}
我试着通过跟随Tim Down的优秀作品,一些Moz和MS文档,以及一些PPK的东西来做到这一点
方法基本上是:
- 将SelectionLikeObject定义为DOM选择或IE选择
- 将RangeLikeObject定义为DOM范围或IE文本范围
- 让
成为一个节点containerNode
- 让
成为一个元素containerElement
- 让
成为节点列表containedElements
- 让
成为RangeLike对象elementRange
- 让
成为一个类似RangeObject的对象selectedRange
- 让
成为元素数组selectedElements
- 让
成为元素元素
- 让
成为selectionlike对象selection
- 从用户的选择中设置
选择
- 将
设置为新数组selectedElements
- 对于
选择中的每个
:选择范围
- 将
设置为containerNode
的公共祖先容器selectedRange
- 将
设置为距离containerElement
最近的元素祖先containerNode
- 将
设置为containedelement
的后代列表containedelement
- 对于
包含元素中的每个
:元素
- 从
设置元素
元素范围
- 如果
的边界在elementRange
:所选范围的边界
- 将
推到元素
上所选元素
- 将
- 从
- 将
DOM分支如下所示:
/**
@param {Document} doc
@return {Array.<Element>}
*/
getSelectedElements.fromIE = function (doc) {
// Selection - http://msdn.microsoft.com/en-us/library/ie/dd347133(v=vs.85).aspx
// TextRange - http://msdn.microsoft.com/en-us/library/dd347140(v=vs.85).aspx
// ControlRange - http://msdn.microsoft.com/en-us/library/ie/ms537447(v=vs.85).aspx
/** @type {TextRange|ControlRange} */
var ieRange = doc.selection && doc.selection.createRange();
/** @type {Array.<Element>} */
var selectedElements = [];
/** @type {TextRange} */
var selectedRange;
/** @type {Element} */
var containerElement;
/** @type {NodeList} */
var containedElements;
/** @type {TextRange} */
var elementRange;
/** @type {Element} */
var element;
/** @type {Selection} */
var selection;
/** @type {number} */
var i = -1;
if (ieRange.text === void 0) {
return []; // FIXME: It's a ControlRange, give up.
}
selectedRange = /** @type {TextRange} */ ieRange;
containerElement = selectedRange.parentElement();
containedElements = containerElement.getElementsByTagName('*');
elementRange = doc.body.createTextRange();
while ((element = containedElements[++i])) {
elementRange.moveToElementText(element);
if (elementRange.compareEndPoints("StartToEnd", selectedRange) > -1 &&
elementRange.compareEndPoints("EndToStart", selectedRange) < 1) {
selectedElements.push(element);
}
}
return /** @type {Array.<Element>} */ selectedElements;
};
/**
@param{Document}doc
@返回{Array.}
*/
getSelectedElements.fromDOM=函数(doc){
/**@type{Range}*/
var选择范围;
/**@type{Array.}*/
var selectedElements=[];
/**@type{Node}*/
var containerNode;
/**@type{Element}*/
var集装箱运输;
/**@type{NodeList}*/
var包含元素;
/**@type{Range}*/
变量元素范围;
/**@type{Element}*/
var元素;
/**@type{Selection}*/
var selection=doc.defaultView.getSelection();
/**@type{number}*/
var rangeCount=selection.rangeCount;
/**@type{number}*/
var元素计数;
/**@type{number}*/
var i;
//没有getRangeAt的浏览器黑客攻击
//看http://www.quirksmode.org/dom/range_intro.html
如果(!selection.getRangeAt){
selection.getRangeAt=函数(i){
/**@type{Range}*/
var range=doc.createRange();
if(i | |!selection.anchorNode){
返回范围;
}
range.setStart(selection.anchorNode,selection.anchorOffset);
range.setEnd(selection.focusNode,selection.focusOffset);
返回范围;
};
selection.rangeCount=1;
}
elementRange=doc.createRange();
对于(i=0;i-1){
选择元素。推送(元素);
}
}
}
elementRange.detach();
返回所选元素;
};
IE分支如下所示:
/**
@param {Document} doc
@return {Array.<Element>}
*/
getSelectedElements.fromIE = function (doc) {
// Selection - http://msdn.microsoft.com/en-us/library/ie/dd347133(v=vs.85).aspx
// TextRange - http://msdn.microsoft.com/en-us/library/dd347140(v=vs.85).aspx
// ControlRange - http://msdn.microsoft.com/en-us/library/ie/ms537447(v=vs.85).aspx
/** @type {TextRange|ControlRange} */
var ieRange = doc.selection && doc.selection.createRange();
/** @type {Array.<Element>} */
var selectedElements = [];
/** @type {TextRange} */
var selectedRange;
/** @type {Element} */
var containerElement;
/** @type {NodeList} */
var containedElements;
/** @type {TextRange} */
var elementRange;
/** @type {Element} */
var element;
/** @type {Selection} */
var selection;
/** @type {number} */
var i = -1;
if (ieRange.text === void 0) {
return []; // FIXME: It's a ControlRange, give up.
}
selectedRange = /** @type {TextRange} */ ieRange;
containerElement = selectedRange.parentElement();
containedElements = containerElement.getElementsByTagName('*');
elementRange = doc.body.createTextRange();
while ((element = containedElements[++i])) {
elementRange.moveToElementText(element);
if (elementRange.compareEndPoints("StartToEnd", selectedRange) > -1 &&
elementRange.compareEndPoints("EndToStart", selectedRange) < 1) {
selectedElements.push(element);
}
}
return /** @type {Array.<Element>} */ selectedElements;
};
/**
@param{Document}doc
@返回{Array.}
*/
getSelectedElements.fromIE=函数(doc){
//选择-http://msdn.microsoft.com/en-us/library/ie/dd347133(v=vs.85).aspx
//文本范围-http://msdn.microsoft.com/en-us/library/dd347140(v=vs.85).aspx
//控制范围-http://msdn.microsoft.com/en-us/library/ie/ms537447(v=vs.85).aspx
/**@type{TextRange | ControlRange}*/
var ieRange=doc.selection&&doc.selection.createRange();
/**@type{Array.}*/
var selectedElements=[];
/**@type{TextRange}*/
var选择范围;
/**@type{Element}*/
var集装箱运输;
/**@type{NodeList}*/
var包含元素;
/**@type{TextRange}*/
变量元素范围;
/**@type{Element}*/
var元素;
/**@type{Selection}*/
var选择;
/**@type{number}*/
var i=-1;
如果(ieRange.text==无效0){
return[];//修复:这是一个控制范围,放弃。
}
selectedRange=/**@type{TextRange}*/ieRange;
containerElement=selectedRange.parentElement();
containedElements=containerElement.getElementsByTagName('*');
elementRange=doc.body.createTextRange();
而((元素=包含元素[++i])){
elementRange.moveToElementText(元素);
如果(elementRange.compareEndPoints(“StartToEnd”,selectedRange)>-1&&
元素范围。比较点(“EndToStart”,selectedRange)<1){
选择元素。推送(元素);
}
}
返回/**@type{Array.}*/selectedElements;
};
现在,我想解决的问题是:如果只选择了元素中的部分文本,那么它将显示在返回的数组中,即使它是唯一的
我想添加一个可以更改的参数