0

好的,这是一个让我很困惑的微笑问题。我正在尝试制作一个 HTML 文本框,当提交时,文本会被扔进一个函数并检查是否有任何链接。如果有链接,则将其包裹在锚标记中并制成可点击的链接。

所以我让那部分工作,但我随后创建了一个编辑功能。因此,当在评论上按下编辑按钮时,会显示一个带有已创建评论的弹出窗口。注释的值(取自 XML 文件)放置在此编辑文本区域的值中。但是links的值还是有anchor标签的,所以看起来非常的乱。

我正在尝试创建一个运行此评论并删除任何锚标记的函数,并且仅在锚标记中保留剩余的文本。

简单的例子,当用户发表评论时,链接如 www.stackoverflow.com,它将被保存在我的 XML 文档中,如下所示:

<a href="www.stackoverflow.com">www.stackoverflow.com</a>

如果用户在开头发布带有 http:// 的链接,它也适用。

我现在正试图将链接恢复为以前的普通文本。

这是我的两个功能。第一个,convertLink完美运行。convertLinkEdit正在尝试恢复该过程,但我没有运气。

function convertLink(text) {
  var words = text.split(' ');
  var newText = '';

  for (var i = 0; i < words.length; i++) {
    var word = words[i];
    if (word.indexOf('http://') === 0) {
      word = '<a href=" ' + word + ' ">' + word + '</a>';
    } else if (word.indexOf('www.') === 0) {
      word = '<a href=" http://' + word + '" >' + word + '</a>';
    }

    newText += word + ' ';
  }

  return newText;
}

function convertLinkEdit(text) {
  var words = text.split(' ');
  var newText = '';

  for (var i = 0; i < words.length; i++) {
    var word = words[i];
    if (word.indexOf('href=') === 0) {
      //if index of finds "href=", it means a link is coming up
      //Therefore, since everything is split at blank spaces,
      //after the next blank space will be the current text that needs saving
    }

    newText += word + ' ';
  }

  return newText;
}

在我的非工作函数内部是关于我认为应该如何完成的评论,尽管我不确定如何实现。

4

4 回答 4

2

实际上,DOM 足够聪明,可以为您将链接解析为文本,因此您可以简单地使用它(链接到 jsFiddle)

function convertLinkEdit(text) {
    // simply create an empty <p> element
    var dummy = document.createElement('p');
    
    // change it's HTML contents to the comment one
    dummy.innerHTML = text;

    // return the TEXT value of our <p>
    return dummy.textContent || dummy.innerText; // we first look up textContent* (newer browsers) and fall back to innerText (older browsers) if needed
}

*有关 textContent 的信息,请参见此处:https ://developer.mozilla.org/en-US/docs/DOM/Node.textContent

我不知道上面的浏览器兼容性,所以,这里是(链接到 jsFiddle) RobG 的变体应用于您的函数:

function convertLinkEdit(text) {
    var dummy = document.createElement('p');
    dummy.innerHTML = text;
    
    var links = dummy.getElementsByTagName('a');
    
    for (var i = 0, l = links.length; i < l; i++)
    {
        var link = links[i];
        var node = document.createTextNode(link.textContent || link.innerText);
        link.parentNode.replaceChild(node, link);
    }
    
    return dummy.textContent || dummy.innerText;
}

仅供参考:您应该始终使用DOM及其用于解析/操作 HTML 的 API。强烈建议不要将 Regex 用于 HTML 解析。
是的,它在某些情况下可能会起作用,但你无法控制它,因为它无法正确区分属性、元素和 DOM 附带的所有其他混乱。

更新:

http://jsfiddle.net/2b8uz/5/这里是更新版本。

问题是,正如 plaxl 已经指出的那样,那个getElementsByTagName和任何其他getElement..家庭成员都将返回一个 NodeList,它是一个 Live 对象。一旦 NodeList 中的元素发生更改,它就会自动更新。

我添加了一个从这里借来的小片段,它将在进入转换循环之前将 NodeList 转换为简单数组。

虽然,如果该函数的第一个版本适合您,请使用那个版本,它应该比循环 2 次要快得多。

于 2013-04-03T04:03:34.573 回答
1

这应该可行,但是可能有更有效的方法来做到这一点。我测试了性能,它似乎比公认的解决方案快得多,但我想它可能不那么可靠。这是测试http://jsperf.com/replace-links

 function convertLinkEdit(text) {
    var rx = /<a [^>]*?href="([^"]+)"[^>]*>[^<]*<\/a>/g;

    convertLinkEdit = function (text) {
        return text.replace(rx, '$1');
    };

    return convertLinkEdit(text);

}
于 2013-04-03T03:26:31.037 回答
0

考虑查找链接,然后将链接元素替换为其内容的文本节点。以下内容将页面中的每个链接替换为其内容:

windowonload = function() {

  var links = document.links;
  var link, node;
  var i = links.length;

  while (i--) {
    link = links[i];
    node = document.createTextNode(link.textContent || link.innerText);
    link.parentNode.replaceChild(node, link);
  }
};
于 2013-04-03T03:21:25.533 回答
0

您可以使用正则表达式来查找href. 因为你的话将是href="someurl">

var res = word.match(/^href="(.+)">/;
if (res && res.length == 2) 
{
     //res[1] will be your url, do whatever you want with it
}

假设您的链接是按照我之前提到的那样创建的,并且您的 href 属性有"而不是'引号。

于 2013-04-03T04:03:15.593 回答