Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Обернуть все элементы, до определённого элемента dom (https://javascript.ru/forum/jquery/16163-obernut-vse-ehlementy-do-opredeljonnogo-ehlementa-dom.html)

majahead 28.03.2011 18:10

Обернуть все элементы, до определённого элемента dom
 
Есть вот такая структура

<div id="some">

<div class="sm_level_1">
<div class="sm_level_2">
<div class="sm_level_2">
<div class="sm_level_1">
<div class="sm_level_2">
<div class="sm_level_3">
<div class="sm_level_3">
<div class="sm_level_2">
<div class="sm_level_3">

</div>

Задача с помощью jquery сделать так чтоб элементы с level_1 по level_n , оборачивались в div

То есть вот так

<div id="some">

<div  class="level_1">

<div class="sm_level_1">
<div class="sm_level_2">
<div class="sm_level_2">

</div>

<div  class="level_2">

<div class="sm_level_1">
<div class="sm_level_2">
<div class="sm_level_3">
<div class="sm_level_3">
<div class="sm_level_2">
<div class="sm_level_3">

</div>

</div>


Пробовал и так и сяк, не получается. Подскажите пожалуйста, что использовать, куда копать? :help:

melky 28.03.2011 23:41

полчаса возился) заинтересовало.

почему ,интересно,не работает фича через $(el).add(i) ( читай : $.add() ) в цикле ???

хз

я пробовал и так и сяк

в итоге плюнул на кеш ( я собирал элементы в массив,но понял потом, " а нахрена?" )

вот код,с которым таки не (!) получилось.
<div id="some">

<div class="sm_level_1">s</div>
<div class="sm_level_2">s</div>
<div class="sm_level_3">s</div>
<div class="sm_level_4">s</div>
<div class="sm_level_5">s</div>
<div class="sm_level_6">s</div>
<div class="sm_level_7">s</div>
<div class="sm_level_8">s</div>
<div class="sm_level_9">s</div>
<div class="sm_level_10">s</div>
    
</div>

скрипт
var fr = 3, // FROM -> с какого
    to = 5, // TO -> по какой
    pr = ".sm_level_", // префикс класса 
    some = $( document.getElementById('some') )  // кешируем родительский элем

/* 

$(pr+fr++,some) ---> some.find(pr+fr++)

pr+fr++ ----->   .sm_level_3,4,5  . с инкрементиком. удобно. заюзали-увеличили
*/
do $(pr+fr++,some).css('color','red');while(fr<=to)
/*
гонялся всегда за умещением кода в одной строчке... маньяк :)

вот тот же цикл ... по-человечески
*/
for(var i = fr; i<=to;i++) {
       $(pr+i,some).css('color','red');
}


// рабочее,чуть-чуть. отмечает говнюков с третьего ( sm_level_3) по пятый (sm_level_5) красным цветом



только вот "нипонять", как обернуть их

делается это через $.wrap()


............

тьфу ты,етить колотить

мануал


var fr = 3,
    to = 5,
    pr = "sm_level_",
    some = $( document.getElementById('some') )
    
some.find('div').wrap(
                      
function(e){
 
/* 
как получить индекс . sm_level_{NUM} -- этот {NUM}

this ->>> html element

$(this) ->>> jQuery el

$(this).attr('class') ->>> 'sm_level_4'

$(this).attr('class').replace(pr,'') = '4'  (строка)

 parseInt(   $(this).attr('class').replace(pr,'') ) ->>> 4 (циферка)

*/
    var inrange = parseInt(   $(this).attr('class').replace(pr,'') );

// просто использую её как кеш,чтобы код читался, и чтобы не создавать еще переменных


    inrange = inrange >= fr && inrange <= to;

// true , если больше либо равен 3, но меньше либо равен 5.. т.е. 3,4,5

    return inrange ? "<s></s>":"";
    
    })


получилось так


<div id="some">

<div class="sm_level_1">s</div>
<div class="sm_level_2">s</div>
<s><div class="sm_level_3">s</div></s>
<s><div class="sm_level_4">s</div></s>
<s><div class="sm_level_5">s</div></s>
<div class="sm_level_6">s</div>
<div class="sm_level_7">s</div>
<div class="sm_level_8">s</div>
<div class="sm_level_9">s</div>
<div class="sm_level_10">s</div>
 
</div>


увы, обернуть одним дивчиком не знаю,как.. $.add() не работает. попробуй через неё ( или через селекторы :gt() и :lt() -> через них у меня тоже не получилось ).

на большее у меня азарта не хватает. спать хочется :)

мб мой сонный мозг чтото пропустил?

буду рад увидеть , как будет решена эта проблема. спокойной ночи :)


и еще, $.index() я не стал использовать не потому что не знал ( а я не знал))) , а потому что
нумерация начинается с единицы ( а может начинаться с тысячи)!

Aetae 29.03.2011 02:02

<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
div {border:1px solid #aac}
div.warp {border:0;background:#dfd}
</style>
</head>
<body>   
<div id="some">

<div class="sm_level_1">s1</div>
<div class="sm_level_2">s2</div>
<div class="sm_level_3">s3</div>
<div class="sm_level_4">s4</div>
<div class="sm_level_5">s</div>
<div class="sm_level_6">s</div>
<div class="sm_level_7">s</div>
<div class="sm_level_8">s</div>
<div class="sm_level_9">s</div>
<div class="sm_level_10">s</div>
    
</div>
<script type="text/javascript">
function createWarp(start,end){
	var e=document.getElementById('some'),
	divs=e.getElementsByTagName('div'),
	i=divs.length,
	elements=[], n, w;

	var warper=document.createElement('div'); warper.className='warp';

	while(i--){
		n = divs[i].className.slice(9); //срезаем sm_level_
		if(n>=start&&n<=end)elements.push(divs[i]);
	}

	var last=elements[0].nextSibling;

	this.warp=function(){
		var i = elements.length; 
		w = w==warper?document.createDocumentFragment():warper;
		while(i--) w.appendChild(elements[i]);
		if(last) e.insertBefore(w,last);
		else e.appendChild(w);
	}
}


//ниже нужно только для демо
w=new createWarp(1,4);
function go(txt){
	if(txt.defaultValue!=txt.value){
		var v=txt.value.split(',');
		w=new createWarp(+v[0],+v[1]);
	}
	txt.defaultValue=txt.value;
	w.warp()
}
  </script>
  <input type = "button" value = "(un)warp" onclick = "go(nextSibling)"/><input type="text" value="1,4"/>
</body>
</html>

Вот простейший примерчик, на коленке.

majahead 29.03.2011 10:09

Всем спасибо, сделал по свойму =)


<div id="some">
	 
	<div class="sm_level_1">
	<div class="sm_level_2">
	<div class="sm_level_2">
	<div class="sm_level_1">
	<div class="sm_level_2">
	<div class="sm_level_3">
	<div class="sm_level_3">
	<div class="sm_level_2">
	<div class="sm_level_3">
	 
	</div>


jQuery("#some").html(""+jQuery("#some").html().replace(/<div class=\"sm_level_1\">/g,"</div><div class='col'><div class='sm_level_1'>").slice(6)+"</div>");


То есть преобразуем в строку, заменяем <div class='sm_level_1'> на </div><div class='col'><div class='sm_level_1'> регулярным выражением) потом удаляем первые 6 символов (то есть первый </div>) и добавляю закрывающий тег в конец "</div>") и вставляем всё это обратно как html . :dance:

Aetae 29.03.2011 17:47

Какой ужас. А то что это будет работать раз в 20 медленней и сбросит все обработчики событий буде такие появятся - похрен.
Впрочем, сам сделал - молодец.)

majahead 30.03.2011 10:45

Aetae ещё до кучи в ие не работает .replace , сразу не проверил ( Работает, но не ищет /<div class=\"sm_level_1\"> / , пробовал всё комментировать и вообще по разному, не хочет и всё... Попробую использовать твой код, спасибо =)

Aetae 30.03.2011 18:15

Скорей всего дело в том, что код <div class="sm_level_1"> обработанный движком IE выглядит примерно так: <DIV class=sm_level_1> не зависимо от того как написан изначально.(кстати для других браузеров по большей части верно обратное)


Часовой пояс GMT +3, время: 08:34.