ivanhjc ivanhjc - 2 months ago 9
Ajax Question

Why is my responseText enclosed in double quotes automatically by the browser when I do loc.innerHTML = xhr.responseText?

I was trying to add a function to my website so that I can insert texts of external files (mainly source code files) to the html page by replacing their paths given within the html tags with the actual text in those files. Specifically, this is done by sending a request to the path and calling

location.innerHTML = xhr.responseText
. However, I found the texts that had been inserted would be enclosed in a pair of double quotes so that they couldn't be read as code snippets and so the syntax highlighting was lost.

Here's a demo of what I'm talking about: ivanhjc.github.io where you can find the first snippet isn't syntax highlighted because it is enclosed in a pair of double quotes as observed in the inspect elements view of Chrome.

When I tried
console.log(responseText)
the quotes didn't show up in the console, and when I tried
responesText.substring(1, responseText.length - 1);
the quotes weren't removed either but instead the first and the last character of the actual text were removed. So the quotes should not be part of the responseText. So I don't understand why they would show up from nowhere.

Here's the source code for your convenience:



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="highlight/styles/darcula.css"/>
<link rel="stylesheet" type="text/css" href="format/universal.css"/>
<script src="highlight/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
<script src="jquery-3.1.0.min.js"></script>
<title>hjcivan</title>
</head>
<body>
<script>
window.onload = function(){
var codes = document.getElementsByTagName("code");
for (var i = 0; i < codes.length; i++) {
var path = codes[i].innerHTML;
console.log(codes[i]);
loadFile(path, codes[i]);
}
test();
/*$("#code").load("Java/src/Factorial.java");*/
};
function loadFile(filePath, location) {
var request = new XMLHttpRequest();
request.open("GET", filePath);
request.onreadystatechange = function () {
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0) {
var codeText = request.responseText;
console.log(codeText);
location.innerHTML = codeText;
hljs.initHighlighting();
}
}
}
request.send(null);
}
function test() {
var p = document.getElementById("test");
p.addEventListener("click", function () {
p.innerHTML = "Yeah!";
});
}
</script>
<h1>Home</h1>
<p>
This is a demo of code snippet:
</p>
<p id="test">I'm here!</p>
<pre><code>Java/src/Factorial.java</code></pre>
<pre><code>
/**
* Fun with factorial
*/
public class Factorial {
/**
* A recursive approach
* @param n A non-negative integer
* @return
*/
public static int calculateRecursively(int n) {
if (n == 1 || n == 0)
return 1;
return calculateRecursively(n - 1) * n;
}

/**
* A loop approach
* @param n
* @return
*/
public static int calculateWithLoop(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}

public static void main(String[] args) {
System.out.println(1);
}
}</code></pre>
</body>
</html>

Answer

The quotes aren't really there. That's just the inspector's way of annotating a text node.

The real problem is that you have to tell the code highlighting library to add syntax highlighting after you've added the new content to the page. The hljs.initHighlighting() you have after the AJAX call doesn't work because you've already called hljs.initHighlightingOnLoad(), and you can init the library only once. Calling initialization functions multiple times doesn't do anything.

If you replace hljs.initHighlighting() with hljs.highlightBlock(location) it should work.

Comments