2011-07-27 29 views
36

Tôi muốn bọc tất cả các nút trong div #slidesContainer bằng JavaScript. Tôi biết nó được thực hiện dễ dàng trong jQuery, nhưng tôi quan tâm đến việc biết làm thế nào để làm điều đó với JS thuần túy.Phương pháp javascript tinh khiết để bao bọc nội dung trong div

Đây là mã:

<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> 

Tôi muốn quấn divs với một lớp học của "trượt" chung trong một div với id="slideInner".

Trả lời

48

Nếu "trượt" của bạn s luôn trong slidesContainer bạn có thể làm điều này

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

Điều đó hoạt động hoàn hảo và đủ đơn giản để tôi hiểu được. Cảm ơn bạn. – Squadrons

+2

@Squadrons: Bạn cũng đang sử dụng jQuery? Nếu vậy, bạn thực sự không nên làm điều này. (Ngay cả khi bạn không, bạn đang phá hủy và tái tạo phần này của DOM không cần thiết.) – user113716

+0

Tôi không sử dụng jquery. Tôi đang cố gắng để có được phần nào thoải mái với JS trước khi tôi chuyển sang một khuôn khổ. Tôi đang thử tất cả các câu trả lời trong chủ đề này, tuy nhiên. Bạn có đề nghị câu trả lời của aroth không? Nếu vậy, tại sao lại là cái này? – Squadrons

11

Nếu bạn patch up document.getElementsByClassName for IE, bạn có thể làm điều gì đó như:

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); 
} 

Ví dụ: http://jsfiddle.net/GkEVm/2/

+0

Bạn có thể muốn kiểm tra câu trả lời của bạn. Có một vài lỗi. – user113716

+0

Cảm ơn sự giúp đỡ nhưng tôi đã nhận được một lỗi phân cấp DOM – Squadrons

+0

@patrick - Có, nó sẽ xuất hiện thứ tự của các hoạt động là tất cả mọi thứ. Nên được cố định ngay bây giờ. – aroth

7

tôi thích thao tác các phần tử dom trực tiếp - createElement, appendChild, removeChild, vv trái ngược với việc tiêm các chuỗi như element.innerHTML. Chiến lược đó hoạt động, nhưng tôi nghĩ rằng các phương pháp trình duyệt nguyên bản trực tiếp hơn. Ngoài ra, chúng trả về giá trị của một nút mới, tiết kiệm cho bạn từ một cuộc gọi getElementById không cần thiết khác.

Điều này thực sự đơn giản và cần được đính kèm với một số loại sự kiện để thực hiện bất kỳ việc sử dụng nào.

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

jsFiddle

lẽ giúp hiểu biết của bạn về vấn đề này với js vani.

+0

Tại sao điều này cần phải được đính kèm? Tôi đã thử chạy nó bằng cách gắn vào một hàm có tên là PrepareSlideshow(), và chạy nó trên tải, nhưng dường như không thể thay đổi DOM để nó hiển thị nút được yêu cầu – Squadrons

+0

Được đính kèm - chỉ để bạn có quyền kiểm soát nó, như sự kiện onLoad mà bạn gọi. Ý tôi là - bạn cũng có thể gọi nó, tôi chỉ cho rằng có một trạng thái trong đó các slide không được bao bọc, và bạn cần phải thay đổi danh sách phần tử của bạn trong thời gian chạy. Chỉ cần chạy trên bất kỳ chức năng nào, và miễn là tên id thành phần của bạn xếp hàng thì nó sẽ hoạt động ... – Bosworth99

16

Giống như BosWorth99, tôi cũng thích điều khiển trực tiếp các phần tử dom, điều này giúp duy trì tất cả các thuộc tính của nút. Tuy nhiên, tôi muốn duy trì vị trí của các yếu tố trong dom và không chỉ nối thêm các trường hợp cuối cùng có anh chị em. Đây là những gì tôi đã làm.

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

Tôi chắc chắn đây là một câu hỏi khó, tôi không quen với javascript/truy vấn như nói CSS, nhưng tại sao bạn sẽ đặt biến này thành một biến thay vì gán nó như một hàm? ví dụ. 'hàm wrap (toWrap, wrapper) {'? – darcher

+0

Tôi thường biểu diễn hàm thay vì khai báo cho kiểu mã hóa nhất quán và đơn giản hóa hành vi hoisting. https: //javascriptweblog.wordpress.com/2010/07/06/function-declarationations-vs-function-expressions/ –

+0

Điều này không trả lời câu hỏi. OP muốn bao bọc tất cả trẻ em không phải là một yếu tố duy nhất. –

0

Từ những gì tôi hiểu câu trả lời @Michal 's là vulnerable to XXS attacks(using innerHTML is a security vulnerability)Here is another link on this.

Có rất nhiều cách để làm điều này, 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); 

này hoạt động tốt. Tuy nhiên đối với tôi, đôi khi tôi chỉ muốn bọc các phần của một nguyên tố. Vì vậy, tôi đã sửa đổi chức năng này:

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); 

Tôi hy vọng điều này sẽ hữu ích.

0

wrapInner nhiều nội dung thẻ


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

Một mẹo tốt chung của cố gắng để làm một cái gì đó bạn thường làm với jQuery, mà không jQuery, is to look at the jQuery source. Họ làm gì?Vâng, họ lấy tất cả các trẻ em, thêm chúng vào một nút mới, sau đó nối thêm nút đó bên trong phụ huynh.

Dưới đây là một phương pháp đơn giản, ít phải làm một cách chính xác rằng:

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

Và đây là cách bạn sử dụng nó:

// 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')) 
Các vấn đề liên quan