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!
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