【问题标题】:Create and Append an element, innerHTML? the horror... [please no jquery]创建并附加一个元素,innerHTML?恐怖... [请不要 jquery]
【发布时间】:2011-11-28 01:13:12
【问题描述】:

我有一个按字母顺序返回列表的脚本,如下所示

<div id="x">
    <ul>
        <li>Apple
        <li>Banana
        <li>Blackberry
        <li>Blueberry
        <li>Cherry
        <li>Cranberry
    </ul>
</div>

但是列表中有很多项目(将近 100 个),我希望将它们重新排列如下

<div id="x">
    <span id="A">A</span>
    <ul>
        <li>Apple
    </ul>
    <span id="B">B</span>
    <ul>
        <li>Banana
        <li>Blackberry
        <li>Blueberry
    </ul>
    <span id="C">C</span>
    <ul>
        <li>Cherry
        <li>Cranberry
    </ul>     
<div>

顺便说一句,我并不是真的在分类水果,这只是一个例子。
它必须是那种形式,出于无关紧要的原因,我只需要帮助创建和附加跨度元素和单个列表。 我尝试过使用内部/外部 HTML,但我发现它真的很难。我目前有这样的事情:

function getAllLists()  
{  
var page = document.getElementById("x")
var allLists = page.getElementsByTagName("li");   
var num = allLists.length;  
//Some form of a for counter loop here
for (var counter = 0; counter < num; counter++) {   
    var first=allLists[counter].outerHTML;
    var second=allLists[counter+1].outerHTML;
    var firstletter= (allLists[counter].substring(0, 1)).toUpperCase();
    var secondletter= (allLists[counter+1].substring(0, 1)).toUpperCase();
    allLists[counter].outerHTML = '<span id="'+firstletter+'">'+firstletter+'</span>'+first;
    }
}

请避免使用 JQUERY。
我怎么强调都不过分!!
我不仅发现它非常难以理解,因为我仍然是 javascript 的业余爱好者,并且发现 js 已经够难了,jquery 的语法就像愚蠢地难以理解。

我确信无需使用 jquery 就可以实现我的目标。

有任何想法吗?所有帮助/cmets/想法都非常感谢。
非常感谢。

【问题讨论】:

  • 我认为你可能错过了 jQuery 的重点,它不是为了让事情变得更困难;这些天大多数人真的不必再直接学习javascript了。
  • @SLaks:有效 - &lt;li&gt; 元素不需要结束标签。
  • @SLaks——怎么样?在我看来很好。应该删除该评论。
  • @BoltClock — outerHTML 在 HTML5 中,但还不是 Firefox(可能还有其他)。 HTML5 的一个目的是记录浏览器中的内容,因此它的存在实际上只是记录常见的当前浏览器功能并鼓励其他人效仿。
  • @Godwin jQuery 可以提供抽象和规范化。 not 是为了避免学习 javascript。请不要建议人们使用他们不理解的抽象

标签: javascript html innerhtml getelementbyid outerhtml


【解决方案1】:

首先忘记使用inner/outerHTML 操作DOM。它们对于插入 HTML 块或文档部分很方便,但它们绝对不适合一般的 DOM 操作。

使用 DOM 方法。

首先,将所有 LI 元素加载到一个数组中。然后使用排序功能对它们进行排序。然后将它们放回被 UL 元素包裹的 DOM 中,并在每次第一个字母发生变化时用 span 分隔。

编辑

这是一个完成这项工作的函数。它对 lIs 进行排序,不确定是否真的需要。如果没有,功能会变得简单很多。

<script type="text/javascript">

// Simple helper
function getText(el) {
  if (typeof el.textContent == 'string') {
    return el.textContent.replace(/^\s+|\s+$/g,'');
  }
  if (typeof el.innerText == 'string') {
    return el.innerText.replace(/^\s+|\s+$/g,'');
  }
}

function sortLIs(id) {
  // Get the element
  var el = document.getElementById(id);

  // Get the UL element that will be replaced
  var sourceUl = el.getElementsByTagName('ul')[0];

  // Get the LIs and put them into an array for sorting
  var nodes = sourceUl.getElementsByTagName('li');
  var li, lis = [];

  for (var i=0, iLen=nodes.length; i<iLen; i++) {
    lis[i] = nodes[i];
  }

  // Sort them
  lis.sort(function(a, b) {
    return  getText(a) > getText(b)? 1 : -1;
  });

  // Now put them into the document in different ULs separated
  // by spans.
  // Create some temporary elements for cloning
  var ul, ulo = document.createElement('ul');
  var sp, spo = document.createElement('span');
  var frag = document.createDocumentFragment(); // fragments are handy
  var firstChar, currentChar;

  // For each LI in the array...
  for (i=0; i<iLen; i++) {
    li = lis[i];
    firstChar = getText(li).substr(0,1) || '';

    // If first char doesn't match current, create a new span
    // and UL for LIs
    if (firstChar !== currentChar) {
      currentChar = firstChar;

      // New span
      sp = spo.cloneNode(false);
      sp.appendChild(document.createTextNode(firstChar.toUpperCase()));
      sp.id = firstChar;
      frag.appendChild(sp);

      // New UL
      ul = ulo.cloneNode(false);
      frag.appendChild(ul);
    }

    // Add the li to the current ul
    ul.appendChild(li);
  }

  // Replace the UL in the document with the fragment
  el.replaceChild(frag, sourceUl);
}

</script>


<div id="x">
    <ul>
        <li>Cherry
        <li>Banana
        <li>Apple
        <li>Blueberry
        <li>Cranberry
        <li>Blackberry
    </ul>
</div>

<button onclick="sortLIs('x');">Sort</button>

请注意,LI 只是移动到文档片段,并且原始 UL 被多个元素替换。我将 LI 弄乱了,以表明排序有效。

编辑 2

如果您将数组作为文本,则:

var fruits = ['Cherry','Banana','Apple','Blueberry',
              'Cranberry','Blackberry'].sort();

function insertFruits(id) {
  var el = document.getElementById(id);

  // Check that the above worked
  if (!el) return;

  var frag = document.createDocumentFragment();
  var li, lio = document.createElement('li');
  var ul, ulo = document.createElement('ul');
  var sp, spo = document.createElement('span');
  var firstChar, currentChar;

  for (var i=0, iLen=fruits.length; i<iLen; i++) {
    fruit = fruits[i];
    firstChar = fruit.substr(0,1).toUpperCase();

    if (firstChar !== currentChar) {
      currentChar = firstChar;
      sp = spo.cloneNode(false);
      sp.appendChild(document.createTextNode(firstChar));
      sp.id = firstChar;
      frag.appendChild(sp);
      ul = ulo.cloneNode(false);
      frag.appendChild(ul);
    }
    li = lio.cloneNode(false);
    li.appendChild(document.createTextNode(fruit));
    ul.appendChild(li);
  }
  el.appendChild(frag);
}

【讨论】:

  • 我已经将它们放在数组allLists 中,按字母顺序排序。我只是不知道如何拔出所有以 A 开头的,并将它们放入自己的ul 中。顺便说一句,感谢您的正确回复。 :)
  • 我也不太清楚 DOM 方法是什么......我做了一些研究,我猜它与创建和插入元素有关? o.O 还在等你的例子。 :S
  • 如果您已经拥有该数组并且只是想将它们放入 UL 中,您应该能够从我发布的代码中到达那里。在“插入 LI”部分,只需创建一个 LI 并附加文本(看看它是如何使用 span 元素完成的)。
  • 你的第一个效果非常好。但是,当我将它添加到我的网站时,它拒绝工作。 =.='我会更加努力的。 :S 非常感谢! :)
  • 抱歉,编辑了第一个并添加了span.id = ... 而不是sp.id = ...。错误消息应该已经告诉你了。
【解决方案2】:

HTML:

<body>
  <div id="x">
    <ul>
        <li>Apple
        <li>Banana
        <li>Blackberry
        <li>Blueberry
        <li>Cherry
        <li>Cranberry
    </ul>
    <ul id="new"></ul>

JavaScript:

var list = document.querySelector('#x ul'),
    newUl = document.getElementById('new'),
    fruits = [],
    key = "A";

for(var i=0; i<list.children.length; i++){
  fruits.push(list.children[i].innerText);
}

fruits.sort();

for(var i=0; i<fruits.length; i++){
  if(key == fruits[i].split('')[0]){
    var span = document.createElement('span'),
        li = document.createElement('li');
    span.setAttribute('id', key);
    li.innerText = fruits[i];
    if(document.getElementById(key)){
      document.getElementById(key).appendChild(li);
    }
    else{
      span.appendChild(li);
      newUl.appendChild(span);
    }

  }
  if(fruits[i+1]){
    key = fruits[i+1].split('')[0];
  }
}

示例:

Live Code

【讨论】:

  • 一些广泛使用的浏览器不支持innerText。
  • document.querySelector() 也不是。
  • innerTextinnerHTML 在这种情况下是相同的。他可以使用innerHTML。此外,如果他们想使用它,他们可以这样做:innerText || textContent。没什么大不了的
  • @BoltClock 我们来这里是为了回答不为人们做事的问题。这回答了上面提出的问题。概念很重要,而不是那些小细节。 IE8 支持querySelectors。我不把 IE7 算作一个广泛使用的浏览器
【解决方案3】:

嗯,这就是我完成它的方式:

var allLists, elements, item, lastLetter, lastUl, letter, page, span, _i, _len;

page = document.getElementById("x");
allLists = page.getElementsByTagName("li");
lastLetter = null;
lastUl = null;
elements = document.createDocumentFragment();

for (_i = 0, _len = allLists.length; _i < _len; _i++) {
  item = allLists[_i];
  letter = item.innerText[0].toUpperCase();
  if (letter !== lastLetter) {
    lastLetter = letter;
    span = document.createElement('span');
    span.innerText = letter;
    span.id = letter;
    elements.appendChild(span);
    lastUl = document.createElement('ul');
    elements.appendChild(lastUl);
  }
  lastUl.appendChild(item.cloneNode(true));
}

while (page.firstChild) page.removeChild(page.firstChild);

page.appendChild(elements.cloneNode(true));

在这里看到这个工作:http://jsfiddle.net/HjWhY/

【讨论】:

  • 尽管使用了 jquery,但您的代码确实可以工作。但是,我鄙视使用 jquery 的另一个原因是因为它不适用于 tumblr ......这就是我所做的一切。但感谢您的回复。 :)
  • 对不起,我只是忘记在侧边栏设置 no-library,但我的代码不需要 jQuery,它是“纯 JS”。 ;)
  • 但是jsfiddle会自动为你加载jquery库。当我尝试将其放入空白的 .html 文件或使用 html Instant 时,它不会运行。 :S 但感谢您的努力。 :)
猜你喜欢
  • 2014-12-26
  • 1970-01-01
  • 2011-09-14
  • 2011-03-02
  • 2020-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多