Показать сообщение отдельно
  #5 (permalink)  
Старый 15.07.2009, 11:15
Аспирант
Отправить личное сообщение для Pattern Посмотреть профиль Найти все сообщения от Pattern
 
Регистрация: 13.05.2009
Сообщений: 37

Всё таки решил я эту задачу, но не полностью. Честно говоря, решение мне то же не очень нравится, очень похоже на "подгонку на ответ", но других мыслей пока не появилось.
В данном решении поиск фразы (например, "body Any text") производится по всему тексту и находит все, кроме 2 мест. В коде так же есть часть закоментированноого кода, которая, если её раскомментировать, находит все вхождения, но выделяет найденный текст со смещением. Как это побороть?
<html>
<head>
<title>Search Text</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<script language="javascript">
function getTextNodeList(parentNode,list){
	for(var a=0;a<parentNode.childNodes.length;a++){
		if(parentNode.childNodes[a].nodeType==3){
			if(parentNode.childNodes[a].nodeValue.length==1&&parentNode.childNodes[a].nodeValue==="\n")
				continue;
			else
				list.push({
					n: parentNode.childNodes[a],
					s: list[list.length-1]?parseInt(list[list.length-1].s)+parseInt(list[list.length-1].l):0,
					l: parentNode.childNodes[a].length
				});
		}else{
			getTextNodeList(parentNode.childNodes[a],list);
		}
	}
}

var storage={
	srch: '',
	lastIdx: -1,
	result: new Array(),
	clear: function(){
		with(storage){
			srch='';
			lastIdx=-1;
			result=new Array();
		}
	},
	search: function(){
		if(storage.srch!==''){
			var b=document.body;
			var list=new Array();
			getTextNodeList(b,list);
			var r=document.createRange();
			r.selectNodeContents(b);
			var c='';
			var v=null;
			for(var a=0;a<list.length;a++){
				v=list[a].n.nodeValue;
				c+=v.replace(/\n/gim," ");
/*
 * Если раскомментировать этот блок, ищет все фразы
 * но "со смещением"
				if(v.charAt(v.length-1)!==" "&&v.charAt(v.length-1)!=="\n"){
					console.log('"'+v+'"');
					c+=' ';
				}
 */
			}
			console.log(c);
			var p=new RegExp(storage.srch,"ig");
			var data=null;
			var startContainer=null;
			var startOffset=0;
			var endContainer=null;
			var endOffset=0;
			var start=0;
			var end=0;
			var ls=0;
			var ll=0;
			while((data=p.exec(c))!=null){
				start=p.lastIndex-storage.srch.length;
				end=p.lastIndex;
				for(var a=0;a<list.length;a++){
					ls=parseInt(list[a].s);
					ll=ls+parseInt(list[a].l);
					if(start>=ls&&start<ll){
						startContainer=list[a].n;
						startOffset=start-ls;
					}
					if(end>=ls&&end<ll){
						endContainer=list[a].n;
						endOffset=end-ls;
					}
				}
				storage.result.push({
					sc: startContainer,
					so: startOffset,
					ec: endContainer,
					eo: endOffset
				});
			}
		}
	},
	init: function(){
		storage.clear();
		if(arguments[0])
			with(storage){
				srch=arguments[0];
				search();
			}
	}
};
function findNext(){
	var i=document.getElementById('srchText');
	if(storage.result.length==0 || (storage.srch!==i.value && i.value!=='')){
		storage.init(i.value);
	}
	if(storage.result.length>0){
		var s=null;
		var r=null;
// for Gecko only
		if(window.getSelection){
			var s=window.getSelection();
			var r=document.createRange();
			storage.lastIdx++;
			if(storage.lastIdx>storage.result.length-1)
				storage.lastIdx=0;
			r.setStart(storage.result[storage.lastIdx].sc,storage.result[storage.lastIdx].so);
			r.setEnd(storage.result[storage.lastIdx].ec,storage.result[storage.lastIdx].eo);
			s.removeAllRanges();
			s.addRange(r);
		}
	}else{
		alert('Совпадений не найдено');
	}
}
</script>
</head>
<body>
Any text into body Any text into body
<div>Any text into body Any text into body <span>Any text into body Any text into body <span>Any text into body Any text into body</span></span></div>
<div>Any text into body Any text into body</div>
<span>Any text into body Any text into body</span>
Any text into body Any text into body
<br />
<input id="srchText" type="text" value="" /><input type="button" value="Search" onclick="findNext()" />
</body>
</html>

Последний раз редактировалось Pattern, 16.07.2009 в 16:29.
Ответить с цитированием