简体   繁体   English

jQuery调用中的顺序

[英]Order in jQuery calls

I have a jQuery loop that iterates over specifics elements of an HTML page. 我有一个jQuery循环,可以遍历HTML页面的特定元素。 For every element, I do a switch over a variable and append HTML code in specific places. 对于每个元素,我都在变量上进行了切换 ,并在特定位置附加了HTML代码。

The problem is that, one of those appends is an import to another Javascript file. 问题在于,这些追加之一是对另一个Javascript文件的导入。 This file uses a variable from the first one but, for some reason, that variable doesn't always have the correct value, depending on the order of the HTML elements in the page. 该文件使用第一个变量,但是由于某种原因,该变量并不总是具有正确的值,具体取决于页面中HTML元素的顺序。

UPDATE UPDATE

As requested, I created a Plunker so it's easy to see code: http://plnkr.co/edit/mrEhgbZhhvu0Z4iniXGl?p=preview 根据要求,我创建了一个Plunker,因此很容易看到代码: http ://plnkr.co/edit/mrEhgbZhhvu0Z4iniXGl?p=preview

Note : For this to work, you need to have correct pageId and appId for Instagram. 注意 :要使其正常工作,您需要为Instagram提供正确的pageIdappId

I'll put the code to be more clear: 我将使代码更清晰:

index.html 的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 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 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 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)
    }
  });
};

Well, I've solved with some ugly lonely line: 好吧,我解决了一些丑陋的孤独行:

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;

Then changed the conf references to instaconf in insta.js file. 然后改变了conf引用instaconfinsta.js文件。

Since this file was loaded after the jQuery loops ended, the configuration was the last one in that loop (the last article in index.html file). 由于此文件是在jQuery循环结束后加载的,因此配置是该循环中的最后一个( index.html文件中的最后一篇文章 )。

Here the problem is you are appending HTML elements dynamically. 这里的问题是您要动态附加HTML元素。 Here jquery will append in DOM then browser will some time to parse. 在这里,jquery将附加在DOM中,然后浏览器将需要一些时间来解析。 Until that controller wont wait for the operation so loop continue execution. 直到该控制器不会等待该操作,然后循环才能继续执行。 so here config is hold last element of twitter configuration. 所以这里config是保存twitter配置的最后一个元素。

And we can't pass reference to html string as per my knowledge. 据我所知,我们无法传递对html字符串的引用。 This we can achieve by passing config as string into html string from there we can pass to fbAsyncInit() method. 我们可以通过将config作为字符串传递到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>';

and we can receive as 我们可以收到

window.fbAsyncInit = function (con) {

or we can pass call back function to html method and we do operation which is done in magic.js 或者我们可以将回调函数传递给html方法,然后执行在magic.js中完成的操作

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

then we can return html accordingly. 那么我们可以相应地返回html。

I hope this will help you. 我希望这能帮到您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM