0

我正在编写一个 javascript 函数来用嵌入代码替换 url(例如,带有 youtube 视频的 youtube url)。我正在考虑将 String.replace() 与以下回调一起使用:

 function replacer(match) {
    if (isYoutubeLink()) {
       return getYoutubeEmbedCode();
    }
    // repeat for other types of urls
 }

但是,由于 getYoutubeEmbedCode() 进行了 oembed api 调用,因此它是异步的,无法返回值。我将如何替换所有网址?

编辑:在用代码替换 url 后,我还需要创建一个新节点,以便视频显示为实际视频,而不仅仅是 html 文本。我认为这意味着我还需要知道所有异步任务何时完成。

4

3 回答 3

0

你应该挂钩到你的异步请求的onreadystatechange

request.open("GET", youtubeurl, true);
request.onreadystatechange = getYoutubeEmbedCode;
request.send(null);

编辑:

http://jsfiddle.net/76dJh/

于 2013-06-06T17:58:51.403 回答
0

传递给它一个闭包,当你完成时会处理它。

function replacer(match) {

    if (isYoutubeLink()) {
       getYoutubeEmbedCode(function(){//code to change URLs here});
    }
    // repeat for other types of urls
}

我不会完全像这样构造我的代码,我会将该闭包抽象为一个对调用范围可见的变量,但这是为了简洁。

- 编辑 -

虽然我意识到这根本不是你想要使用的方法。您正在寻找替换链接(锚标记)本身,而不是它们的 href 属性。

1) 选择您希望更改为 youtube 视频的所有锚标签并将它们存储在一个数组中。如果你给他们一个类或数据属性,这很容易(在这种情况下我更喜欢数据属性,因为它使比较更容易并且不太可能与基本的 css 类发生冲突)。

2)循环遍历它们,并比较它们的 href 值或它们的数据属性名称(<--这是使用数据属性的优势),以决定基于每个元素提取哪个 youtube vid。将 ajax 调用传递给传递目标锚标记的回调函数(我在原始帖子中提到的闭包)。

3)当ajax返回时使用目标锚标记将youtube代码放在它之后(使用append或类似的东西)。

4)删除目标锚标签。

5) 现在你想在视频之后添加一些东西,因为你有视频在这里,你现在可以通过定位它来做。

全部完成。

在我看来,这是一种更好的方法。也许我错过了你的帖子的重点,但从我读到的内容听起来你的方法是试图做一些你真正想做的事情之外的事情。

于 2013-06-06T17:59:27.187 回答
-1

恐怕您必须编写自己的字符串替换器。也许是这样的:

function replace_async(str, pattern, replacer, cb) {
  var result = '';
  function _(arg) {
    result += arg;
    var first_match = pattern.exec(str);
    if (!first_match) {
      result += str;
      return cb(str);
    }
    result += str.substr(0, first_match.index);
    str = str.substr(first_match.index+first_match.input.length);
    replacer(first_match, _);
  }
  _('');
}

然后你可以像这样编写异步替换回调:

replace_async("foo bar http://youtube.com/... baz http://youtube.com", url_pattern, function(match, cb) {
  getYoutubeEmbedCode(match.input, cb);
}, function(result) {
  alert("Text with translated URLs:\n"+result);
});

当然,您也可以只执行同步请求作为解决方法,但这并不是一个好主意。

于 2013-06-06T18:13:19.623 回答