jQuery调用中的顺序

时间:2018-10-26 06:56:32

标签: javascript jquery html node.js

我有一个 jQuery 循环,该循环遍历 HTML 页面的特定元素。对于每个元素,我都会对变量进行 switch 并将 HTML 代码附加到特定位置。

问题在于,其中一个附加项是对另一个 Javascript 文件的导入。该文件使用第一个变量,但是由于某种原因,该变量并不总是具有正确的值,具体取决于页面中 HTML 元素的顺序。

  

更新

     

根据要求,我创建了一个Plunker,因此很容易看到代码:   http://plnkr.co/edit/mrEhgbZhhvu0Z4iniXGl?p=preview

     

注意:要使其正常工作,您需要具有正确的 pageId appId < / strong>用于Instagram。

我将使代码更清晰:

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Demo</title>
    <link rel="stylesheet" href="estilo.css">
  </head>
  <body>
    <section id="rrss">
      <!-- If I put this article block as the last one, it works -->
      <article id="instagram">
        <div data-rrss="instagram"></div>
      </article>
      <br/>
      <article id="facebook">
        <div data-rrss="facebook"></div>
      </article>
      <br/>
      <article id="twitter">
        <div data-rrss="twitter"></div>
      </article>
    </section>

    <!-- SCRIPTS -->
    <script src='scripts/data.js'></script>
    <script src='scripts/jquery.js'></script>
    <script>var customJquery = $.noConflict(true);</script>
    <script src='../magic.js'></script>
  </body>
</html>

data.js

var data = {
  "facebook": {
    "id": "facebook",
    "width": 0,
    "height": 0,
    "custom_style": "border:none;overflow:hidden",
    "hide_cover": false,
    "show_facepile": true,
    "small_header": false,
    "adapt_container_width": true
  },
  "twitter": {
    "id": "twitter",
    "width": 0,
    "height": 0,
    "chrome": "nofooter noscrollbar noheader", // noborders  transparent
    "tweet_limit": 0,
    "lang": "es",
    "theme": "dark",
    "link_color": "#0084b4"
  },
  "instagram": {
    "id": "123456798123467/9876543219876543",
    "hidecaption": false,
    "custom_style": "overflow:auto;",
    "max_width": 0,
    "max_height": 500
  },
  "defaults": {
    "width": 380,
    "height": 500
  }
}

magic.js

var rrss = customJquery('div[data-rrss]');
var conf = undefined;
var defaults = undefined;
var node = document.querySelectorAll('[data-rrss="instagram"]')[0];

customJquery.each(rrss, function(ix, it) {
    var html = '';

    var network = customJquery(it).data('rrss');

    if (network === undefined || network == null || network.length <= 0)
        return;


    conf = data[network];

    if (conf === undefined ||conf === null || conf.length <= 0)
        return;

    defaults = data['defaults'];

    //Comprobamos si existe el key y si el value tiene texto
    if(conf.id === undefined || conf.id === null || conf.id.length === 0)
        return;

    switch(network) {
        case 'facebook':
            html =  '<iframe id="iFB" src="https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2F' + conf.id +
                        '&tabs=timeline' +
                        '&width=' + (conf.width <= 0 ? defaults.width : conf.width) +
                        '&height=' + (conf.height <= 0 ? defaults.height : conf.height) +
                        '&small_header=' + conf.small_header +
                        '&adapt_container_width=' + conf.adapt_container_width +
                        '&hide_cover=' + conf.hide_cover +
                        '&show_facepile=' + conf.show_facepile + '"' +
                        'width="' + (conf.width <= 0 ? defaults.width : conf.width) + '" ' +
                        'height="' + (conf.height <= 0 ? defaults.height : conf.height) + '" ' +
                        'style="' + conf.custom_style + '" ' +
                        'scrolling="no" frameborder="0" allowTransparency="true" allow="encrypted-media"></iframe>\n' +
                    '<script type="text/javascript">\n' +
                    '  setInterval(() => {\n' +
                    '    customJquery("#iFB")[0].src = customJquery("#iFB")[0].src\n' +
                    '  }, 5 * 60 * 1000);\n'
                    '</script>';
        break;
        case 'twitter':
            html =  '<a class="twitter-timeline" '+
                        'href="https://twitter.com/' + conf.id + '" ' +
                        'data-width="' + (conf.width <= 0 ? defaults.width : conf.width) + '" ' +
                        'data-height="' + (conf.height <= 0 ? defaults.height : conf.height) + '" ';

            if (conf.chrome !== undefined && conf.chrome !== '') {
                html += 'data-chrome="' + conf.chrome + '" ';
            }

            if (conf.tweet_limit > 0) {
                html += 'data-tweet-limit="' + conf.tweet_limit + '" ';
            }

            html += 'data-lang="' + conf.lang + '" ' +
                    'data-theme="' + conf.theme + '" ' +
                    'data-link-color="' + conf.link_color + '"' +
                    '>Tweets by ' + conf.id + '</a>\n' +
                    '<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>';
        break;
        case 'instagram':
            node = node.parentElement;
            html =  '<script async src="https://connect.facebook.net/es_ES/sdk.js"></script>\n' +
                    '<script src="../insta.js"></script>\n' +
                    '<script async defer src="https://www.instagram.com/embed.js"></script>\n' +
                    '<script>\n'+
                    '  setInterval(() => {\n' +
                    '    if (document.readyState === "complete") {\n' +
                    '      window.instgrm.Embeds.process();\n' +
                    '    }\n' +
                    '  }, 100);\n' +
                    '  setInterval(() => {\n' +
                    '    fbAsyncInit();\n' +
                    '  }, 5 * 60 * 1000);\n'
                    '</script>';
        break;
        default:
            html = '';
    }

    if (html != '') {
        customJquery(it).replaceWith(html);
    }
});

insta.js

window.fbAsyncInit = function () {
  var html = '';
  var style = '';

  // When the Instagram's article bloke in HTML isn't the last one, this shows data from Twitter bloke
  console.log(conf);

  if (node !== undefined) {
    if (document.getElementById('instagram') !== null) {
      document.getElementById('instagram').innerHTML = '';
    }

    if (conf !== undefined && conf !== '') {
      if (conf.max_width !== undefined && conf.max_width > 0) {
        style += 'max-width: ' + conf.max_width + 'px;';
      } else {
        style += 'max-width: ' + defaults.width + 'px;';
      }

      if (conf.max_height !== undefined && conf.max_height > 0) {
        style += 'max-height: ' + conf.max_height + 'px;';
      } else {
        style += 'max-height: ' + defaults.height + 'px;';
      }

      style += conf.custom_style;
    }

    var div = document.createElement('div');
    div.id = 'instagram';

    if (style !== '') {
      div.style = style;
    }

    node.appendChild(div);
  }

  var pageId = conf.id.substring(0, conf.id.indexOf('/'));
  var appId = conf.id.substring(conf.id.indexOf('/') + 1);

  FB.init({
    appId: appId,
    autoLogAppEvents: true,
    xfbml: true,
    version: "v3.1"
  });

  FB.getLoginStatus(function (response) {
    if (response.status === "connected") {
      FB.api(
        "/" + pageId + "/",
        "GET", { "fields": "instagram_business_account" },
        function (response) {
          if (response.error && response.error !== '') {
            console.log("Error recovering 'instagram_business_account': " + response.error.message);
          } else {
            FB.api(
              "/" + response.instagram_business_account.id + "/media",
              "GET", { "fields": "shortcode" },
              function (response) {
                for (var i = 0; i < response.data.length; i++) {
                  var xhttp = new XMLHttpRequest();

                  xhttp.onreadystatechange = function() {
                    if (this.readyState == 4 && this.status == 200) {
                      html = JSON.parse(this.response).html;
                      document.getElementById("instagram").innerHTML += html;
                    }
                  };

                  xhttp.open("GET", "https://api.instagram.com/oembed/?url=http://instagr.am/p/" + response.data[i].shortcode + "&omitscript=true&hidecaption=" + conf.hidecaption, true);
                  xhttp.send();
                }
              }
            );
          }
        }
      );
    } else {
      console.log("Error recovering access token: Not connected.")
      console.log(response)
    }
  });
};

2 个答案:

答案 0 :(得分:0)

好吧,我解决了一些丑陋的孤独行:

case 'instagram':
    node = node.parentElement;
    instaconf = conf; // ***** Saved the conf here *****
    html = '<script async src="https://connect.facebook.net/es_ES/sdk.js"></script>\n' +
           '<script src="../tecInsta.js"></script>\n' +
           '<script async defer src="https://www.instagram.com/embed.js"></script>\n' +
           '<script>\n'+
           '  setInterval(() => {\n' +
           '    if (document.readyState === "complete") {\n' +
           '      window.instgrm.Embeds.process();\n' +
           '    }\n' +
           '  }, 100);\n' +
           '  setInterval(() => {\n' +
           '    fbAsyncInit();\n' +
           '  }, 5 * 60 * 1000);\n'
           '</script>';
    break;

然后将 insta.js 文件中的conf引用更改为instaconf

由于此文件是在 jQuery 循环结束之后加载的,因此配置是该循环中的最后一个( index.html 中的最后一个 article 文件)。

答案 1 :(得分:0)

这里的问题是您要动态附加HTML元素。在这里,jquery将附加在DOM中,然后浏览器将需要一些时间来解析。直到该控制器不会等待该操作,然后循环才能继续执行。所以这里config是保存twitter配置的最后一个元素。

据我所知,我们无法传递对html字符串的引用。我们可以通过将配置作为字符串传递到html字符串中来实现,然后再传递给fbAsyncInit()方法。

                    '<script>\n'+
                '  setInterval(() => {\n' +
                '    if (document.readyState === "complete") {\n' +
                '      window.instgrm.Embeds.process();\n' +
                '    }\n' +
                '  }, 100);\n' +
                '  setInterval(() => {\n' +
                ' let configuration = '+ JSON.stringify(conf) +';'+
                '    fbAsyncInit(configuration);\n' +
                '  }, 5 * 60 * 1000);\n'
                '</script>';

我们可以收到

window.fbAsyncInit = function (con) {

或者我们可以将回调函数传递给html方法,然后执行在magic.js中完成的操作

参考:http://api.jquery.com/html/#html-function

然后我们可以相应地返回html。

我希望这会对您有所帮助。