dougang8233 2013-09-16 23:48
浏览 44
已采纳

在ajax完成之后,加载<script>标签,但只加载具有特定id的标签

I'm currently using infinite-scroll to load more content, the content has <script> tags that need to be ran. So I'm using the code below as an ajax-callback:

JS on load ajax callback:

function ajaxLoadedCallback() {
      // contentElem is the HTML element you've loaded via ajax
      scriptx = document.getElementsByTagName("script");

      // Load scripts into new array because 
      // scriptx seems to change as scripts execute, at least in some browsers
    scripts = new Array();
    for (var idx=0; idx<scriptx.length; idx++) {

        if (jQuery(scriptx[idx]).is("#inline-comments")) {
                scripts[idx] = scriptx[idx].text;
        }

    }

        console.log (scripts[idx]);
      // execute each script in turn
      for(idx=0; idx<scripts.length; ++idx) {
         if (scripts[idx].length!=0) {
            try {
              // create a function for the script & execute it
              f = new Function(scripts[idx]);
              f();
            } catch(se) {

            } // end try-catch
         } // end if
      } // end for

}

Each content post has this script tag I want to load:

<script id="inline-comments" >
    console.log ('<?php echo $post->ID; ?>' + 'has loaded...');
    var tid_<?php echo $post->ID; ?> = setInterval( function () {
    if ( document.readyState !== 'complete' ) return;
        clearInterval( tid_<?php echo $post->ID; ?> );       
        inline_comments_ajax_load(<?php echo $post->ID; ?>)
    }, 100 );   
</script>

Getting an Uncaught TypeError: Cannot read property 'length' of undefined error on this line: if (scripts[idx].length!=0) {

The ajax call back loads at the right time, but breaks because I assume scripts[idx] is empty. but why? when I use console.log() it shows when the scriptx[idx] has an id and the name of the id.

UPDATE Thank you PSL! console.log shows that it is finding the scripts, but scripts.length is returning zero

function ajaxLoadedCallback() {
    scriptx = document.getElementsByTagName("script");


    scripts = new Array();
    for (var idx=0; idx<scriptx.length; idx++) {

        if (jQuery(scriptx[idx]).is(".inline-comments-script")) {
            console.log (".inline-comments-scriptfound!");
            console.log ("####### .text #######");
            console.log (scriptx[idx].text);
            console.log ("####### .innerHTML ######");
            console.log (scriptx[idx].innerHTML);
            scripts.push = scriptx[idx].innerHTML;
        }

    }
    console.log ("####### END ######");
    console.log ("Found "+scripts.length+ " script(s)");

      // execute each script in turn
      for(idx=0; idx<scripts.length; ++idx) {
        var content = scripts[idx];
            if (content.length) {
                try {
              // create a function for the script & execute it
              f = new Function(content);
              f();
            } catch(se) {

            } // end try-catch
         } // end if
      } // end for

}

Works now! See PSL's answer below - you can also see it live if you have wordpress: https://github.com/MattMcFarland/inline-ajax-comments - works great!

  • 写回答

1条回答 默认 最新

  • douruye5092 2013-09-17 00:12
    关注

    You have couple of issues here.

    for (var idx=0; idx<scriptx.length; idx++) {
    
            if (jQuery(scriptx[idx]).is("#inline-comments")) {
                    scripts[idx] = scriptx[idx].text;
            }
    
        }
    

    You are incrementing the loop iteration variable eventhough there is no match and you dont want to push any item to the array. So if the first script does not match your condition scripts[0] will be undefined hence you get the error when you tru to acces the property length of undefined in your condition if (scripts[idx].length!=0) {

    Another issue is that scriptx[idx].text here text is a function so you want the real text of the element and not the function reference so you should write jQuery(scriptx[idx]).text() or scriptx[idx].innerHTML. Since you are using id and ids are not supposed to be duplicated you can simply write this as:

         var txt = jQuery('#inline-comments').text();
         if (txt.length) {
            try {
              // create a function for the script & execute it
              f = new Function(scripts[idx]);
              f();
            } catch(se) {
    
            } // end try-catch
         } // end if
    

    If you plan to turn inline-comments to class from id and you are looking to access multiple of them then this should work.

     scripts = [];
        for (var idx=0; idx<scriptx.length; idx++) {
            if (jQuery(scriptx[idx]).is(".inline-comments")) {
                    scripts.push(scriptx[idx].innerHTML);
            }
         }
         // execute each script in turn
          for(idx=0; idx<scripts.length; ++idx) {
              var content = scripts[idx];
             if (content.length) {
                try {
                  // create a function for the script & execute it
                  f = new Function(content);
                  f();
                } catch(se) {
    
                } // end try-catch
             } // end if
          } // end for
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 有赏,i卡绘世画不出
  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码