javascript - Wie sollte ich den von mir geschriebenen Code optimieren, um Objektdaten in DOM-Knoten zu konvertieren?
三叔
三叔 2017-06-12 09:28:43
0
3
948

Eine kurze Einführung in die Idee:
Ajax zum Objekt, dann vom Kind zum Elternteil Objekte erstellen, Stile festlegen und Ebenen hinzufügen.
Dann sieht der Code so aus:

function Activity(obj) {
  var activityContent = document.createElement('a');
  activityContent.innerHTML = obj.post.c;
  activityContent.className = 'activity-content';
  activityContent.style.overflow = 'hidden';
  activityContent.href = '/t/'+obj.tid+'#'+obj.pid;
  var activityTitleText = document.createElement('span');
  activityTitleText.innerHTML = obj.oc.t;
  activityTitleText.style.overflow = 'hidden';
  var activityTitle = document.createElement('p');
  activityTitle.className = 'activity-title';
  var activityTitleA = document.createElement('a');
  activityTitleA.appendChild(activityTitleText);
  activityTitleA.href = '/t/'+obj.tid;
  var activityInfo = document.createElement('span');
  activityInfo.className = 'activity-info';
  if(obj.forum) {
    var color = obj.forum.color || 'orange';
    var forum = document.createElement('a');
    forum.href= '/f/'+obj.fid;
    var forumText = document.createElement('span');
    forumText.className = 'activity-title-forum';
    forumText.style.backgroundColor = color;
    forumText.innerHTML = ' '+obj.forum.abbr+' ';
    forum.appendChild(forumText);
    activityTitle.appendChild(forum);
  }
  if(obj.toMyForum) {
    var color = obj.toMyForum.color || 'orange';
    var toMyForum = document.createElement('a');
    toMyForum.href= '/m/'+obj.toMyForum._key;
    var toMyForumText = document.createElement('span');
    toMyForumText.className = 'activity-title-forum';
    toMyForumText.style.backgroundColor = color;
    toMyForumText.innerHTML = ' '+obj.toMyForum.abbr+' ';
    toMyForum.appendChild(toMyForumText);
    activityTitle.appendChild(toMyForum);
  }
  if(obj.myForum) {
    var color = obj.myForum.color || 'orange';
    var myForum = document.createElement('a');
    myForum.href= '/m/'+obj.myForum._key;
    var myForumText = document.createElement('span');
    myForumText.className = 'activity-title-forum';
    myForumText.style.backgroundColor = color;
    myForumText.innerHTML = ' '+obj.myForum.abbr+' ';
    myForum.appendChild(myForumText);
    activityTitle.appendChild(myForum);
  }
  activityTitle.appendChild(activityTitleA);
  activityInfo.appendChild(activityTitle);
  activityInfo.appendChild(activityContent);
  var activityUser = document.createElement('p');
  activityUser.className = 'activity-user';
  activityUserA = document.createElement('a');
  activityUserA.href = '/activities/'+obj.uid;
  var activityUserAvatar = document.createElement('img');
  activityUserAvatar.className = 'activity-user-avatar';
  activityUserAvatar.src = '/avatar/'+ obj.uid;
  activityUserA.appendChild(activityUserAvatar);
  var username = document.createElement('a');
  username.href = '/activities/'+obj.uid;
  username.innerHTML = obj.user.username;
  activityUser.appendChild(activityUserA);
  activityUser.appendChild(username);
  var type;
  switch (obj.type) {
    case 1:
      type = 'Po';
      break;
    case 2:
      type = 'Re';
      break;
    case 4:
      type = 'Rc';
      break;
    default:
      type = 'X';
  }
  var activityType = document.createElement('p');
  activityType.className = 'activity-type';
  var activityTypeText = document.createElement('p');
  activityTypeText.className = 'activity-type-text';
  activityTypeText.innerHTML = type;
  var activityTypeDate = document.createElement('p');
  activityTypeDate.className = 'activity-type-date';
  activityTypeDate.innerHTML = moment(obj.time).fromNow();
  activityType.appendChild(activityTypeText);
  activityType.appendChild(activityTypeDate);
  var activity = document.createElement('p');
  activity.className = 'activity';
  activity.appendChild(activityType);
  activity.appendChild(activityUser);
  activity.appendChild(activityInfo);
  return activity;
}

Das ist es. . . Wie optimieren?
Die Front-End-Unterstützung für ES6 ist nicht ideal, daher kann die String-Vorlage nicht verwendet werden und es ist schwierig, ein Framework hinzuzufügen. Was soll ich tun, wenn es zum Schreiben gezwungen wird?
Was sind die Nachteile dieser Schreibweise im Vergleich zur String-Verkettung und dann direkt innerHTML?

三叔
三叔

Antworte allen(3)
代言

首先,JS 人肉维护 DOM 的【过程式编程】在可维护性上是劣于模板风格的【声明式编程】的。考虑一行简单的 <p>xxx</p> 和一大坨 document.createElement('p')...,它们在可维护性上有天壤之别。

那么,怎样在没有 ES6 或各种框架语法糖的情况下,采用类似字符串模板的方式,将数据绑定到 HTML 呢?这里有一种 jQuery 作者曾经推荐的方案:

首先可以在 HTML 里搞个猥琐的 <script> 标签装模板,注意这个模板本身对 JS 并没有任何依赖,也可以把模板放在 <body> 外面。

<script id="my-template" type="text/x-custom-template">
    <p class="xxx">
        <p class="yyy">%name%</p>
        <p class="zzz">%value%</p>
    </p>
</script>

渲染数据时,直接取出模板中的 HTML 文本,用 JS 做正则替换即可:

var template = document.getElementById("my-template").innerHTML;
var html = template
            .replace(/%name%/, data['name'])
            .replace(/%value%/, data['value']);
// insert HTML...

参考我的这篇博客:
http://ewind.us/2016/js-rende...

当然,全量重置 innerHTML 是有性能风险的。但如果数据全量更新,那么即便是原生 JS 编写的代码,最后的 DOM 操作次数和直接重置 innerHTML 实际上是一样的。这时有几种思路:

  1. React 就是为了这类问题而生的。把 React 当做你的 innerHTML,随便全量重置,React 帮你 diff 然后按需更新 DOM,岂不美哉?

  2. Vue 通过依赖收集,直接能够找到变动的 DOM 所在位置并按需更新,连 diff 都不用,更是不知道高到哪里去了。

  3. 自己维护符合业务需求的 diff 算法(如只插入末尾)和 DOM 操作。也许是一个新轮子诞生的前奏呢(

滿天的星座

结构太复杂,不优雅,纯粹是 肉抗,而且debug简直就是噩梦,以后代码维护量太大!
建议使用 前端 JS模板引擎,eg:artTemplate,就引入一个 JS 文件而已。

漂亮男人

最简单的优势:比innerHTML快。
当你一次性添加几百个这种结构的时候,你就能体会到明显的速度差异

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage