Javascript pulling content from commented html - javascript

Bit of a JS newbie, I have a tracking script that reads the meta data of the page and places the right scripts on that page using this:
var element = document.querySelector('meta[name="tracking-title"]');
var content = element && element.getAttribute("content");
console.log(content)
This obviously posts the correct tag to console so I can make sure it's working .. and it does in a test situation. However, on the actual website the meta data i'm targeting is produced on the page by a Java application and beyond my control, the problem is it is in a commented out area. This script cannot read within a commented out area. ie
<!-- your tracking meta is here
<meta name="tracking-title" content="this-is-the-first-page">
Tracking finished -->
Any ideas appreciated.

You can use this code:
var html = document.querySelector('html');
var content;
function traverse(node) {
if (node.nodeType == 8) { // comment
var text = node.textContent.replace(/<!--|-->/g, '');
var frag = document.createDocumentFragment();
var div = document.createElement('div');
frag.appendChild(div);
div.innerHTML = text;
var element = div.querySelector('meta[name="tracking-title"]');
if (element) {
content = element.getAttribute("content");
}
}
var children = node.childNodes;
if (children.length) {
for (var i = 0; i < children.length; i++) {
traverse(children[i]);
}
}
}
traverse(html);

One way is to use a NodeIterator and get comment nodes. Quick example below. You will still need to parse the returned value for the data you want but I am sure you can extend this here to do what you want.
Fiddle: http://jsfiddle.net/AtheistP3ace/gfu791c5/
var commentedOutHTml = [];
var iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_COMMENT, NodeFilter.FILTER_ACCEPT, false);
var currentNode;
while (currentNode = iterator.nextNode()) {
commentedOutHTml.push(currentNode.nodeValue);
}
alert(commentedOutHTml.toString());

You can try this. This will require you to use jQuery however.
$(function() {
$("*").contents().filter(function(){
return this.nodeType == 8;
}).each(function(i, e){
alert(e.nodeValue);
});
});

Related

I'm trying to parse all the urls of the tabs I have open

I'm trying to copy the url's of all the open tabs with javascript and then put the urls into a html textarea, however it's not working.
This is my code.
chrome.windows.getCurrent({"populate":true}, function(currentWindow) {
var tabURLs = [];
var tabs = currentWindow.tabs;
for (var i=0; i<tabs.length; i++) {
tabURLs.push(tabs[i].url);
}
var textArea = document.getElementById("thing");
var text = textArea.value;
tabURLs.forEach(item => text += item);
});
};
Keep in mind this is a google chrome extension, let me know how I can fix this!
Your code is modifying a copy of the element's value, not the element itself.
You need to replace text += with textArea.value +=
P.S. The code can be shortened:
chrome.tabs.query({}, tabs => {
document.getElementById("thing").value = tabs.map(t => t.url).join('\n');
});

Google Apps Script - Move Cursor onclick

I would like to implement a Table of Contents in the sidebar of a Google Docs document which will take you to the appropriate sections when clicked. I am generating the HTML for the sidebar element by element, and I see that there is a moveCursor(position) function in Document class, but I can't see how to actually call it using onclick. Not the full code but shows the problem:
function generateHtml() {
var html = HtmlService.createHtmlOutput('<html><body>');
var document = DocumentApp.getActiveDocument();
var body = document.getBody();
//Iterate each document element
var totalElements = body.getNumChildren();
for(var i = 0; i < totalElements; ++i) {
var element = body.getChild(i);
if(element.getType() == DocumentApp.ElementType.PARAGRAPH) {
var text = paragraph.getText();
if(text.trim()) { //Not blank paragraph
var position = document.newPosition(element, 0);
/**Would like to have <a onclick=document.moveCursor(position)> here**/
//Show first 20 chars as preview in table of contents
html.append('Detected paragraph ')
.append(text.substring(0, 20))
.append('<br />');
}
}
}
html.append('</body></html>');
return html;
}
How can I accomplish this in Apps Script? The code can be completely restructured as needed.
This line:
/**Would like to have <a onclick=document.moveCursor(position)> here**/
Change to:
<div onmouseup="myClientFunction()">Text Here</div>
Add a <script> tag to your HTML:
<script>
var valueToSend = code to get value;
window.myClientFunction = function() {
google.script.run
.myGsFunctionToMoveCursor(valueToSend);
};
</script>
Then you need a myGsFunctionToMoveCursor() function in a script file (.gs extension)
function myGsFunctionToMoveCursor(valueReceived) {
//To Do - Write code to move cursor in Google Doc
. . . Code to move cursor
};

Javascript, Firefox replacing entire document without document.write

I have this method, which works fine, except in Firefox:
function write(template) {
document.open("text/html", "replace");
document.write(template);
document.close();
}
write("<!DOCTYPE html><head><title>MyPage</title></head><body>111</body><html>");
In firefox the entire page can no longer be refreshed and when you update the hash in the address field it forces a complete refresh of the page.
This doesn't happen in chrome.
Is there a different way to update entire document that makes Firefox play along?
Thanks!
-----------EDIT----------
I noticed there is a document.childNodes[0].remove() method to call which will remove the old document, but I am unable to add a new document node to that array.
var node = document.createElement("html");
node.innerHTML = "<body>1111</body>";
document.childNodes[0].remove();
document.childNodes[0] = node;
Does not seem to be working. Any hints?
-----------EDIT 2 ----------
function write(template) {
var node = document.createElement("html");
node.innerHTML = template;
var head = node.getElementsByTagName("head")[0];
var body = node.getElementsByTagName("body")[0];
if ( head ) {
document.documentElement.replaceChild(
head,
document.documentElement.getElementsByTagName("head")[0]
);
}
if ( body ) {
document.documentElement.replaceChild(
body,
document.documentElement.getElementsByTagName("body")[0]
);
}
}
This successfully does replace the dom, unfortunately, unlike write it doesn't revaluate the style or script tags, making it useless :(
------- EDIT 3 -------
Yields the same as EDIT 2 making it also useless:
function write(template) {
var node = document.createElement("html");
node.innerHTML = template;
document.replaceChild(node, document.childNodes[0]);
}
----- EDIT 4 -----
See my answer below
Apparently, jQuery is able to revaluate scripts when html() is used correctly, here is the write method :
function write(template) {
var node = document.createElement("html");
node.innerHTML = template;
var head = node.getElementsByTagName("head")[0];
var body = node.getElementsByTagName("body")[0];
if ( head ) {
jQuery("head").html(head.innerHTML);
}
if ( body ) {
jQuery("body").html(body.innerHTML);
}
}
write("<!DOCTYPE html><head><title>MyPage</title></head><body>111</body><html>");
:D
I would recommend you to make use of the .html() function of jQuery. (or innerHTML if you prefer to make use of pure Javascript)
If the document DOM has already been loaded you shouldn't be using document.write.
After replacing the DOM, you can manually revalute scripts and styles, by creating new elements:
function write(template) {
var node = document.createElement("html");
node.innerHTML = template;
var head = node.getElementsByTagName("head")[0];
var body = node.getElementsByTagName("body")[0];
if ( head ) {
document.documentElement.replaceChild(
head,
document.documentElement.getElementsByTagName("head")[0]
);
}
if ( body ) {
document.documentElement.replaceChild(
body,
document.documentElement.getElementsByTagName("body")[0]
);
}
var scripts = document.getElementsByTagName("script"),
styles = document.getElementsByTagName("style");
var or_scripts_length = scripts.length,
or_styles_length = styles.length;
//reproduce scripts
for(var i=0; i<or_scripts_length; i++){
new_script = document.createElement("script");
new_script.setAttribute("src", scripts[i].src);
document.head.appendChild(new_script);
if(i == or_scripts_length)
break; //in order to avoid revaluating new created scripts which results to an infinite loop
}
//do the same for styles
}

Google news box within div

I'm trying to place a google news search within a div on my site. I'm currently using the script google provides, but am a novice at Ajax/JavaScript. I am able to display the most recent stories from google news, but don't know how to have it display within a div let alone manipulate the style with CSS. Below is the code I'm using. Any help would be greatly appreciated!
<script type="text/javascript">
google.load('search', '1');
var newsSearch;
function searchComplete() {
// Check that we got results
document.getElementById('averagecontainer').innerHTML = '';
if (newsSearch.results && newsSearch.results.length > 0) {
for (var i = 0; i < newsSearch.results.length; i++) {
// Create HTML elements for search results
var p = document.createElement('p');
var a = document.createElement('a');
a.href = newsSearch.results[i].url;
a.innerHTML = newsSearch.results[i].title;
// Append search results to the HTML nodes
p.appendChild(a);
document.body.appendChild(p);
}
}
}
function onLoad() {
// Create a News Search instance.
newsSearch = new google.search.NewsSearch();
// Set searchComplete as the callback function when a search is
// complete. The newsSearch object will have results in it.
newsSearch.setSearchCompleteCallback(this, searchComplete, null);
// Specify search quer(ies)
newsSearch.execute('Barack Obama');
// Include the required Google branding
google.search.Search.getBranding('branding');
}
// Set a callback to call your code when the page loads
google.setOnLoadCallback(onLoad);
</script>
If I understand correctly, this is what you need:
Create the <div> and give it an ID:
<div id="your-div">HERE BE NEWS</div>
Then modify the searchComplete funcion like this:
function searchComplete() {
var container = document.getElementById('your-div');
container.innerHTML = '';
if (newsSearch.results && newsSearch.results.length > 0) {
for (var i = 0; i < newsSearch.results.length; i++) {
// Create HTML elements for search results
var p = document.createElement('p');
var a = document.createElement('a');
a.href = newsSearch.results[i].url;
a.innerHTML = newsSearch.results[i].title;
// Append search results to the HTML nodes
p.appendChild(a);
container.appendChild(p);
}
}
}
As for style manipulation, you can match the elements by the given ID in css. For example like this:
#your-div a {
font-weight: bold;
}
EDIT:
To show you that this is working, I have created a jsfiddle: http://jsfiddle.net/enjkG/
There is not a lot of things you can mess up here. I think you may have a syntactic error and did not check the console for errors.

Find an anchor in a Div with javascript

In javascript I have a reference to a div. In that div is an anchor element with a name='foundItem'
How do I get a reference to the anchor with the name foundItem which is in the Div I have the reference of?
There are 'many' foundItem anchors in other divs on the page. I need 'this' DIVs one.
// assuming you're not using jquery or mootools
// assume div is mydiv
var lst = mydiv.getElementsByTagName('a');
var myanchor;
for(var i=0; i<lst.length; ++i) {
if(lst[i].name && lst[i].name == 'foundItem') {
myanchor = lst[i];
break;
}
}
// the mootools method
var myanchor = $(mydiv).getElement('a[name=foundItem]');
You can use the getElementsByTagName method to get the anchor elements in the div, then look for the one with the correct name attribute:
var found = null;
var e = divReference.getElementsByTagName('A');
for (var i=0; i < e.length; i++) {
if (e[i].name && e[i].name == 'foundItem') {
found = e[i];
break;
}
}
If found is not null, you got the element.
If you happen to use the jQuery library, you can let it do the searching:
var found = null;
var e = $(divReference).find('a[name=foundItem]');
if (e.length == 1) found = e.get(0);
Use a JavaScript library like jQuery and save yourself time.
var theAnchor = $('#divId a[name=foundItem]');
Using jquery, it's dead easy:
<script type="text/javascript">
$(function(){
var item = $("#yourDivId a[name=foundItem]")
)};
</script>
Update:
As per the comments, if you have control over what to id/name/class your anchor tag/s, it would be best to apply a class to them:
<div id="firstDiv">
test
</div>
<div id="secondDiv">
test another one
</div>
<!-- and so forth -->
<script type="text/javascript">
$(function(){
var item = $("#firstDiv a.foundItem");
alert(item.html()); // Will result in "test"
var item2 = $("#secondDiv a.foundItem");
alert(item2.html()); // Will show "test another one"
)};
</script>
If you're doing anything with javascript, jQuery saves you tons of time and is worth investing the effort to learn well. Start with http://api.jquery.com/browser/ to get an intro to what's possible.
Not sure if this helps, but wanted a function to handle the load of a page dynamically and scroll to the anchor of choice.
function scrollToAnchor(anchor_val) {
alert("" + anchor_val);
var page = document.getElementById('tables');
var found = null;
var cnt = 0;
var e = document.getElementsByTagName('a');
for (var i = 0; i < e.length; i++) {
if (e[i].name && e[i].name == anchor_val) {
found = e[i];
break;
}
cnt++;
}
if (found) {
var nPos = found.offsetTop;
alert("" + nPos);
page.scrollBy(0, nPos);
} else {
alert('Failed with call of scrollToAnchor()' + cnt);
}
}

Categories

Resources