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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题