2011-07-27 7 views
36

Quiero envolver todos los nodos dentro del div #slidesContainer con JavaScript. Sé que se hace fácilmente en jQuery, pero estoy interesado en saber cómo hacerlo con JS puro.Método de JavaScript puro para ajustar el contenido en un div

Aquí está el código:

<div id="slidesContainer"> 
    <div class="slide">slide 1</div> 
    <div class="slide">slide 2</div> 
    <div class="slide">slide 3</div> 
    <div class="slide">slide 4</div> 
</div> 

quiero envolver los divs con una clase de "slide" colectivamente dentro de otro div con id="slideInner".

Respuesta

48

Si sus s "Slide" están siempre en slidesContainer usted puede hacer esto

org_html = document.getElementById("slidesContainer").innerHTML; 
new_html = "<div id='slidesInner'>" + org_html + "</div>"; 
document.getElementById("slidesContainer").innerHTML = new_html; 
+1

Eso funcionó perfectamente, y fue lo suficientemente simple como para que incluso yo lo entendiera. Gracias. – Squadrons

+2

@Squadrons: ¿También está usando jQuery? Si es así, realmente no deberías hacer esto. (Incluso si no lo eres, estás destruyendo y recreando innecesariamente esta parte del DOM.) – user113716

+0

No estoy usando jquery. Estoy tratando de sentirme un poco cómodo con JS antes de pasar a un marco. Estoy probando todas las respuestas en este hilo, sin embargo. ¿Recomiendas la respuesta de aroth? Si es así, ¿por qué sobre este? – Squadrons

11

Si patch up document.getElementsByClassName for IE, se puede hacer algo como:

var addedToDocument = false; 
var wrapper = document.createElement("div"); 
wrapper.id = "slideInner"; 
var nodesToWrap = document.getElementsByClassName("slide"); 
for (var index = 0; index < nodesToWrap.length; index++) { 
    var node = nodesToWrap[index]; 
    if (! addedToDocument) { 
     node.parentNode.insertBefore(wrapper, node); 
     addedToDocument = true; 
    } 
    node.parentNode.removeChild(node); 
    wrapper.appendChild(node); 
} 

Ejemplo: http://jsfiddle.net/GkEVm/2/

+0

Es posible que desee probar su respuesta. Tengo algunos errores. – user113716

+0

Gracias por la ayuda pero estaba obteniendo un error de jerarquía DOM – Squadrons

+0

@patrick - Sí, parece que el orden de las operaciones es todo. Debería ser arreglado ahora. – aroth

7

I gusta manipular elementos dom directamente - createElement, appendChild, removeChild etc. en lugar de la inyección de cadenas como element.innerHTML. Esa estrategia funciona, pero creo que los métodos de navegador nativos son más directos. Además, devuelven el valor de un nuevo nodo y lo salvan de otra llamada innecesaria getElementById.

Esto es realmente simple, y tendría que adjuntarse a algún tipo de evento para hacer cualquier uso.

wrap(); 
function wrap() { 
    var newDiv = document.createElement('div'); 
    newDiv.setAttribute("id", "slideInner"); 
    document.getElementById('wrapper').appendChild(newDiv); 
    newDiv.appendChild(document.getElementById('slides')); 
} 

jsFiddle

Tal vez que ayuda a su comprensión de este tema con js vainilla.

+0

¿Por qué necesita esto adjuntarse? Intenté ejecutarlo adjuntándome a una función llamada prepareSlideshow(), y ejecutándolo en la carga, pero parece que no puedo modificar el DOM para que muestre el nodo requerido – Squadrons

+0

Adjunto, solo para que tenga control sobre él, como el evento onLoad tu llamada. Quiero decir, podrías llamarlo también, solo asumí que había un estado en el que las diapositivas no estaban envueltas, y que necesitabas alterar tu lista de elementos durante el tiempo de ejecución. Solo ejecute cualquier función, y mientras sus nombres de identificación de elementos se alineen debería funcionar ... – Bosworth99

16

Al igual que BosWorth99, también me gusta manipular los elementos dom directamente, esto ayuda a mantener todos los atributos del nodo. Sin embargo, quería mantener la posición del elemento en el dom y no solo anexar el extremo en caso de que hubiera hermanos. Aquí esta lo que hice.

var wrap = function (toWrap, wrapper) { 
    wrapper = wrapper || document.createElement('div'); 
    toWrap.parentNode.appendChild(wrapper); 
    return wrapper.appendChild(toWrap); 
}; 
+1

Estoy seguro de que esta es una pregunta pobre, no estoy tan familiarizado con javascript/query como dice CSS, pero ¿por qué? ¿Configurarías esto como una variable en lugar de asignarlo como una función? p.ej. 'function wrap (toWrap, wrapper) {'? – darcher

+0

Generalmente utilizo expresiones en lugar de declaraciones para un estilo de codificación consistente y para simplificar el comportamiento de elevación. https: //javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/ –

+0

Esto no responde la pregunta. El OP quiere envolver a todos los niños ni un solo elemento. –

0

Por lo que entiendo respuesta @Michal 's es vulnerable to XXS attacks(using innerHTML is a security vulnerability)Here is another link on this.

Hay muchas maneras de hacer esto, one that I found and liked is:

function wrap_single(el, wrapper) { 
    el.parentNode.insertBefore(wrapper, el); 
    wrapper.appendChild(el); 
} 
let divWrapper; 
let elementToWrap; 
elementToWrap = document.querySelector('selector'); 
// wrapping the event form in a row 
divWrapper = document.createElement('div'); 
divWrapper.className = 'row'; 
wrap_single(elementToWrap, divWrapper); 

Esto funciona bien. Sin embargo, a veces, solo quiero envolver partes de un elemento. Así que modifiqué la función a esto:

function wrap_some_children(el, wrapper, counter) { 
    el.parentNode.insertBefore(wrapper, el); 
    if (! counter) { 
    counter = el.childNodes.length; 
    } 
    for(i = 0; i < counter; i++) { 
    wrapper.appendChild(el.childNodes[0]); 
    } 
} 
// wrapping parts of the event form into columns 
let divCol1; 
let divCol2; 
// the elements to wrap 
elementToWrap = document.querySelector('selector'); 
// creating elements to wrap with 
divCol1 = document.createElement('div'); 
divCol1.className = 'col-sm-6'; 
divCol2 = document.createElement('div'); 
divCol2.className = 'col-sm-6'; 
// for the first column 
wrap_some_children(elementToWrap, divCol1, 13); // only wraps the first 13 child nodes 
// for the second column 
wrap_some_children(elementToWrap, divCol2); 

Espero que esto ayude.

0

wrapInner contenido de la etiqueta múltiples


function wilWrapInner(el, wrapInner) { 
    var _el = [].slice.call(el.children); 
    var fragment = document.createDocumentFragment(); 
    el.insertAdjacentHTML('afterbegin', wrapInner); 
    var _wrap = el.children[0]; 
    for (var i = 0, len = _el.length; i < len; i++) { 
    fragment.appendChild(_el[i]); 
    } 
    _wrap.appendChild(fragment); 
} 

Link Demo Jsbin

0

Un buen consejo general para tratar de hacer algo que normalmente haces con jQuery, sin jQuery, is to look at the jQuery source. ¿Qué hacen?Bueno, agarran a todos los niños, los añaden a un nuevo nodo, luego añaden ese nodo dentro del padre.

Aquí es un método poco simple de hacer precisamente eso:

const wrapAll = (target, wrapper = document.createElement('div')) => { 
    ;[ ...target.childNodes ].forEach(child => wrapper.appendChild(child)) 
    target.appendChild(wrapper) 
    return wrapper 
} 

Y aquí es cómo lo usa:

// wraps everything in a div named 'wrapper' 
const wrapper = wrapAll(document.body) 

// wraps all the children of #some-list in a new ul tag 
const newList = wrapAll(document.getElementById('some-list'), document.createElement('ul')) 
Cuestiones relacionadas