0

I have a website with a lot of posts with <table> and a new responsive layout.

When big table elements (lot of content) are opened on mobile devices, even with max-width: 100% or other CSS tricks, they get bigger than the screen.

The solution is append tables in a overflow: scroll <div>, but I can't edit all the post content, so I want to do that with pure Javascript. jQuery not allowed.

The objetive is:

  1. Get all <table> elements of the page that are inside #post
  2. Get their content
  3. Append that content in a <div class="table_div"> in the same place that the <table> is
  4. Remove old table elements (the ones that are not inside .table_div)

I already can get all content from table elements and remove the tables, but the part of the code that supposedly should append table content in .table_div do not work.

Part of my code so far:

    var post = document.getElementById('post'),
    tables = post.getElementsByTagName('table');

for(var i=0; i<tables.length; i++) {
    var table = tables[i];

    var table_content = table.innerHTML,
        table_div = document.createElement('div');

    tables.remove();

    table_div.appendChild(table);
    table_div.className = 'table_div';
    document.appendChild(table_div);
}

Full code: http://jsfiddle.net/hmaesta/6mambr93/

Please, help with just pure Javascript. Thank you.

Programmeur
  • 1,483
  • 4
  • 22
  • 32

2 Answers2

2

See this updated fiddle:

var post = document.getElementById('post'),
    tables = post.getElementsByTagName('table');

for(var i=0; i<tables.length; i++) {
    var table = tables[i];

    var elem = document.createElement('div');
    elem.className = 'table_div';

    post.replaceChild(elem, table);

    elem.appendChild(table);
}

I used the replaceChild method to first replace the table element with a newly created div. Then I append the original table element to that div.

Marvin
  • 13,325
  • 3
  • 51
  • 57
2

NodeList has two mode; static or live (ref When is NodeList live and when is it static?). Live means that changes in the DOM are reflected in the NodeList. And NodeList from getElementsByTagName is live. In your code, the length of tables is decremented everytime you remove #post table.

There is some way to solve the problem.

  1. Use static NodeList. For example, querySelectorAll returns static one.
  2. Map NodeList to Array. You can do this with var ts = []; Array.prototype.push.apply(ts, tables);. And after this, use ts instead of tables.
  3. Keep length and order of NodeList. Use insertChild instead of appendChild to keep order and to keep <table> in #post.

Here is example.

var tables = document.querySelectorAll('#post table');
for(var i = 0; i < tables.length; i++) {
    var table = tables[i];
    var table_div = document.createElement('div');
    table.parentElement.insertBefore(table_div, table);
    table_div.className = 'table_div';
    table_div.appendChild(table);
}

https://jsfiddle.net/boy48ngs/2/

Note: You do not need to remove <table> manually in this case. Element cannot has multiple parents and appendChild removes the element from current parent.

Community
  • 1
  • 1
tetsurom
  • 113
  • 1
  • 7