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

Выделение одиночных тэгов
Привет!
Разрабатываю html-редактор. Чтобы изменить свойства какого либо объекта, понятное дело, требуется его выделение. Для "двойных тэгов" (типо <tag></tag>) проблем никаких не возникает, так как ссылку на объект легко получить через parentNode относительно позиции курсора. А вот с выделением одиночных тэгов (таких как <br/>, <hr/>, <input/>, <img/> и прочие) столкнулся с проблемой. Никак не могу сообразить, как узнать что пользователь выделил одиночный тэг?
Ниже привожу код, который отвечает за "сборку" дерева нодов относительно текущей позиции курсора. При каждом изменении позиции важно определить, что либо выделяется некая область редактируемого текста, либо просто происходит переменещие по нему.
При вызове getTreeNodes() опередяется с какого нода будет собираться дерево нодов, вплоть до <body>. Соответсвенно нужно знать:
- либо если выделена вся нода, сборка начнётся с неё
- либо сборка начнётся с родительского нода; тут же, если выделен какой то участок, он заносится в clipboard (для каких либо дальнейших операций).
Выделение одиночных тэгов в коде у меня определяются как range.commonAncestorContainer с длиной выделенного текста 0. То есть подобно тому, что курсор установлен где то в тексте без выделения.
Кто знает, как получить ссылку на выделенный объект, помогите разобраться?
jsCore.storage={
	parentObject: null,
	range: null,
	buffer: '',
	clipboard: null,
	savedCopy: null,
	tree: null,
/**
 * Функция получения выделенного объекта
 * срабатывает при любом изменении позиции текстового курсора
 */
	get: function(){
//объект источника данных
		obj=arguments[1]||richedit||null;
//событие, вызвавшее функцию
		e=arguments[0]||window.event
//		jsCore.debug(e,17,'storage.js');
//		e=e||window.event||null;
//		var target=(e!=null && e.target!=null ? e.target : e.srcElement);
		var range=null;
//Gecko, Opera
		if(jsCore.browser.isGecko() || jsCore.browser.isOpera()){
//Если выделение произвелось в редактируемой области
			if(obj.contentWindow.getSelection){
//Выделенная область
				var buffer=obj.contentWindow.getSelection();
//Сохраняем объект range
				range=buffer.getRangeAt(0);
//Если ничего не выделено
				if(range.offsetStart==range.offsetEnd && range.startContainer==range.endContainer && buffer.toString().length==0){
//Для дальнейшей работы потребуется ссылка на выделенный объёкт
					jsCore.storage.range=range;
//Если выделена какая то область
				}else{
//Создаем объект, с помощью которого можно получить HTML содержимое выделенного объекта
					jsCore.storage.clipboard=jsCore.dom.create.tag('span');
//В clipboard сохраняем HTML-содержимое выделенного объекта
					jsCore.storage.clipboard.appendChild(range.cloneContents());
//В buffer сохраняем текст выделенного объекта
					jsCore.storage.buffer=buffer;
					jsCore.storage.range=range;
				}
				return true;
			}
//IE
		}else if(jsCore.browser.isIE()){
//Если выделение произвелось в редактируемой области
			if(re_doc.selection){
				range=re_doc.selection.createRange();
				jsCore.storage.buffer=range.text;
				jsCore.storage.clipboard=range.htmlText;
				return true;
			}else{
				jsCore.storage.clear();
				return false;
			}
		}else{
			jsCore.storage.clear();
			return false;
		}
		return true;
	},
	getTreeNodes: function(){
		jsCore.storage.get(richedit);
		if(jsCore.storage.range){
			var o=null;
			jsCore.debug(jsCore.storage.range,67,'storage.js::range');
			if(jsCore.storage.clipboard
				&& jsCore.storage.clipboard.childNodes
				&& jsCore.storage.clipboard.childNodes.length==1
				&& jsCore.storage.clipboard.childNodes[0].nodeType!=3
				&& jsCore.storage.clipboard.childNodes[0].innerHTML==jsCore.storage.buffer){
					o=jsCore.storage.range.startContainer.childNodes[0];
					jsCore.debug(o,74,'storage.js::currentNode');
			}else{
				if(jsCore.storage.range.commonAncestorContainer.nodeType!=3){
					o=jsCore.storage.range.commonAncestorContainer;
					jsCore.debug(o,78,'storage.js::commonAncestorContainer');
				}else{
					o=jsCore.storage.range.commonAncestorContainer.parentNode;
					jsCore.debug(o,81,'storage.js::parentNode');
				}
			}
			if(o){
				if(o.tagName==null){
					jsCore.debug(o,86,'storage.js::-=[ !!! BUG !!! ]=-');
				}else{
					if(o.tagName.toLowerCase()!='html'){
						jsCore.storage.tree=new Array();
						while(o && o.tagName.toLowerCase()!='body'){
							if(o.tagName){
								jsCore.storage.tree.push(o);
								o=o.parentNode;
							}else{
								o=o.parentNode;
							}
							if(o==null)
								break;
							if(o.tagName==null)
								o=o.parentNode;
						}
						if(o)
							jsCore.storage.tree.push(o);
					}
				}
			}
		}
	}
};
Изображения:
Тип файла: jpg editor_img.jpg (16.3 Кб, 26 просмотров)
Ответить с цитированием