Using script variables in html body - javascript

I want to call the variable from the script to body.
Here is my script code. I want to take the rightanswers and wronganswers values to use in html body.
GetFeedback = function (a) {
if (a == CorrectAnswer) {
rightanswers++;
} else {
wronganswers++;
}
lock = true;
}

You need to use the Document Object Modle. You have different methods with JavaScript to create and insert elements into the DOM. As for example:
var element = document.createElement('p');
var body = document.body;
body.appendChild(element);
With that code you are creating an element, then appendig it into the body. And that is pure JavaScript. You could use Mootools or jQuery, and It is goign to be simpler. But JavaScript doesn't work like PHP for example, where you can use the variables mixed up with the HTML.
And if you want to trigger the function from the HTML you need to bind thtat function to an event. For example clicking on a link would be.
HTML
Click Here
JS
var b = document.getElementById('button');
b.click = function(){
GetFeedback();
}

Make sure you're declaring the variable (we can't see that in the code provided) by using var:
<script>
var GetFeedback = function (a) {
if (a == CorrectAnswer) {
rightanswers++;
} else {
wronganswers++;
}
lock = true;
</script>
Then in your HTML, you can use feedback like this (although, it's not good practice to use the below, it's merely for demonstration purposes):
Hello

you can use jquery to change the html on the page.
GetFeedback = function(a){
if(a==CorrectAnswer){
rightanswers++;
}else{
wronganswers++;
}
lock=true;
$('p:first').html('Right Answers: '+rightanswers+' <br> Wrong Answers: '+wronganswers);
};
and have this as your html
<body>
<p></p>
Get Feedback
</body>

Related

How to get a list of Javascript functions in a specific <script> tag

Using the HTML below, how can I get a list of the functions in the <script> tag that is IN the #yesplease div. I don't want any other functions from other script tags. I don't want any global functions or native functions. What I'd like is an array with "wantthis1" and "wantthis2" only in it. I'm hoping not to have to use regex.
I am going to be emptying and filling the #yesplease div with different strings of html (including new script tags with new functions), and I need to make sure that I delete or "wantthis1 = undefined" each function in the script tag before filling it, programmatically, since I won't know every function name. (I don't want them to remain in memory)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
function dontCare() {
// don't care
}
</script>
</head>
<body>
<div id="notthisone">
<p>
Hello
</p>
<script>
function dontwantthis () {
// nope
}
</script>
</div>
<div id="yesplease">
<p>
Hello again
</p>
<script>
function wantthis1 () {
// yes
}
function wantthis2 () {
// yes
}
</script>
</div>
<script>
// this function can be called by whatever, but this will look to
// see if functions exist, then call them, otherwise do something
// else
function onSaveOrWhatever () {
if (wantThis1 !== "undefined") {
wantThis1();
}
else {
// do something else (won't get called with above example)
}
if (wantThis3 !== "undefined") {
wantThis3();
}
else {
// do something else (will get called with above example)
}
}
</script>
</body>
</html>
Take innerHTML of all script tags you need
Create an iframe
Get a list of built-in functions of iframe.contentWindow object
Write the content of the script to the iframe created
Get a new list of the functions of iframe.contentWindow object
Find new functions added to the new list
Somehow it doesn't work in stack snippets but it works in Codepen link
var code = document.querySelector("#target script").innerHTML;
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
var builtInFunctions = getFunctionsOfWindowObject();
var html = `<html><head><script>${code}</script></head><body /></html>`;
iframe.srcdoc = html;
var allFunctions = getFunctionsOfWindowObject();
var result = allFunctions.filter(function(n) {
return builtInFunctions.indexOf(n) < 0;
});
console.log(result);
function getFunctionsOfWindowObject() {
var functions = [];
var targetWindow = iframe.contentWindow;
for (var key in targetWindow) {
if (
targetWindow.hasOwnProperty(key) &&
typeof targetWindow[key] === "function"
) {
functions.push(key);
}
}
return functions;
}
iframe {
display: none;
}
<div id="target">
<script>
function wantthis1() {}
function wantthis2() {}
</script>
</div>
The are a few ways to solve this problem
Architect your application. Use react or vue (or even jquery) to add more control to your code/dom
AST parsing, which would be overkill
Hack it
If you hack it, the problem that you will face is that you are adding functions to global scope. This is shared by everyone, so you can't really monitor it in a nice way.
You can however take advantage of javascript singlethreadedness, and know that things won't happen in the background while you are doing monitoring tasks.
<script>
// take a cache of what is present before your script
window.itemsPresentBeforeScript = {};
foreach (var item in window) {
window.itemsPresentBeforeScript[item] = window[item];
}
</script>
<script> .... your other script </script>
<script>
// use your first cache to see what changed during the script execution
window.whatWasAddedInTheLastScript = {};
foreach (var item in window) {
if (!window.itemsPresentBeforeScript[item]) {
window.whatWasAddedInTheLastScript[item] = window[item];
}
}
delete window.itemsPresentBeforeScript;
// not you have a global list of what was added and you can clear it down when you need to
</script>

How to select/hide elements inside an object of type "text/html" using javascript [duplicate]

I'm using the object tag to load an html snippet within an html page.
My code looks something along these lines:
<html><object data="/html_template"></object></html>
As expected after the page is loaded some elements are added between the object tags.
I want to get those elements but I can't seem to access them.
I've tried the following
$("object").html() $("object").children() $("object")[0].innerHTML
None of these seem to work. Is there another way to get those elements?
EDIT:
A more detailed example:
consider this
<html><object data="http://www.YouTube.com/v/GGT8ZCTBoBA?fs=1&hl=en_US"></object></html>
If I try to get the html within the object I get an empty string.
http://jsfiddle.net/wwrbJ/1/
As long as you place it on the same domain you can do the following:
HTML
<html>
<object id="t" data="/html_template" type="text/html">
</object>
</html>
JavaScript
var t=document.querySelector("#t");
var htmlDocument= t.contentDocument;
Since the question is slightly unclear about whether it is also about elements, not just about the whole innerHTML: you can show element values that you know or guess with:
console.log(htmlDocument.data);
The innerHTML will provide access to the html which is in between the <object> and </object>. What is asked is how to get the html that was loaded by the object and inside the window/frame that it is producing (it has nothing to do with the code between the open and close tags).
I'm also looking for an answer to this and I'm afraid there is none. If I find one, I'll come back and post it here, but I'm looking (and not alone) for a lot of time now.
No , it's not possible to get access to a cross-origin frame !
Try this:
// wait until object loads
$('object').load(function() {
// find the element needed
page = $('object').contents().find('div');
// alert to check
alert(page.html());
});
I know this is an old question, but here goes ...
I used this on a personal website and eventually implemented it in some work projects, but this is how I hook into an svg's dom. Note that you need to run this after the object tag has loaded (so you can trigger it with an onload function). It may require adaptation for non-svg elements.
function hooksvg(elementID) { //Hook in the contentDocument of the svg so we can fire its internal scripts
var svgdoc, svgwin, returnvalue = false;
var object = (typeof elementID === 'string' ? document.getElementById(elementID) : elementID);
if (object && object.contentDocument) {
svgdoc = object.contentDocument;
}
else {
if (typeof object.getSVGDocument == _f) {
try {
svgdoc = object.getSVGDocument();
} catch (exception) {
//console.log('Neither the HTMLObjectElement nor the GetSVGDocument interface are implemented');
}
}
}
if (svgdoc && svgdoc.defaultView) {
svgwin = svgdoc.defaultView;
}
else if (object.window) {
svgwin = object.window;
}
else {
if (typeof object.getWindow == _f) {
try {
svgwin = object.getWindow();//TODO look at fixing this
}
catch (exception) {
// console.log('The DocumentView interface is not supported\r\n Non-W3C methods of obtaining "window" also failed');
}
}
}
//console.log('svgdoc is ' + svgdoc + ' and svgwin is ' + svgwin);
if (typeof svgwin === _u || typeof svgwin === null) {
returnvalue = null;
} else {
returnvalue = svgwin;
}
return returnvalue;
};
If you wanted to grab the symbol elements from the dom for the svg, your onload function could look like this:
function loadedsvg(){
var svg = hooksvg('mysvgid');
var symbols = svg.document.getElementsByTagName('symbol');
}
You could use the following code to read object data once its loaded completely and is of the same domain:
HTML-
<html>
<div class="main">
<object data="/html_template">
</object>
</div>
</html>
Jquery-
$('.main object').load(function() {
var obj = $('.main object')[0].contentDocument.children;
console.log(obj);
});
Hope this helps!
Here goes a sample piece of code which works. Not sure what the problem is with your code.
<html>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var k = $("object")[0].innerHTML;
alert(k);
$("object")[0].innerHTML = "testing";
});
</script>
<object data="/html_template">hi</object>
</html>
UPDATED
I used this line of Javascript to change the value of a input filed inside an iFrame, taken from How to pick element inside iframe using document.getElementById:
document.getElementById('iframeID').contentWindow.document.getElementById('inputID').value = 'Your Value';
In your case, since you do not have a frame, and since you want to get and not set the value, log it for example with:
console.log(document.getElementById('object').value);
And if you guess or choose an element:
console.log(document.getElementById('object').data);

Calling javascript function in html second time

Below is my code for a simple text based game that i am trying to make but i cannot understand why the first time i call my function with a hyperlink 'link1', it works but when i add another link to my html document using javascript, and try to call another function onclick upon that link, it doesn't work. can somebody explain?
var getupvar = document.getElementById("attack");
getupvar.onclick = attack;
function attack() {
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
}
var link2event = document.getElementById("defend");
link2event.onclick = defend;
function defend() {
alert("working now");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="console">
<p id="startGameMessage"></p>
<div id="gameArea">
<p id="gameMessage">Some Text</p>
link1
<div id="placeHolder"></div>
</div>
</div>
When you link up your attack onclick, the element exists. But because #defend does not exist on the dom when you run var link2event = document.getElementById("defend");, your onclick never gets set.
Instead try:
var getupvar = document.getElementById("attack");
getupvar.onclick = attack;
function attack(){
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
var link2event = document.getElementById("defend");
link2event.onclick= defend;
}
function defend(){
alert("working now");
}
jsfiddle https://jsfiddle.net/fv9mpbm6/
This will get your code working how you wish. If you don't do so, your code cannot work because the two lines added to the attack() function will be executed when you call the .js file in your html document as a script and not as a function. This means that the method getElementById("defend") will not find anything, because when you initialize the page, you cannot find any element with this id, you create it when you click on the link.
But do note that if you click attack more than once, your code will break because there will be more than one defend element.
When creating dynamic content, never use ids for handlers! Use classes instead
function attack() {
$('link2').insertBefore("#placeHolder");
}
Also, to ensure proper handling for elements that may not exist yet, leverage jquery's on functionality
$('body').on('click', '.defend', function() {
alert("working now")
})
it is simple, just put the two lines of code
var link2event = document.getElementById("defend");
link2event.onclick= defend;
inside the attack() function, at the end,and it works. This is the new attack() function:
function attack(){
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
var link2event = document.getElementById("defend");
link2event.onclick= defend;}
If you don't do so this code cannot works because these two lines will be executed when you call the .js file in your html document as a script and not as a function. This means that the method getElementById("defend") will not find nothing, because when you initialize the page, you cannot find any element with this id, you create it when you click on the link.
I hope that this helps!
Cheers!
Try this, I am not sure is this what you expect
var getupvar = document.getElementById("attack"), i=0;
getupvar.onclick = attack;
function attack() {
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
var link2event = document.getElementById("defend"+i);
link2event.onclick = defend;
i++;
}
function defend() {
alert("working now");
}

Saving some contenteditables localstorage - - -

I'm trying to save more than one entry of contenteditable content into my localstorage for a Chrome extension. My current code saves just one contenteditable section fine, but when I try to add another Id of a seperate contenteditable section it either deletes all the saved information or doesn't do anything at all. I'm pretty novice in JS, so I hope I'm just making a simple mistake. My html looks like this:
<div id = "content">
<div id= "tcontent" contenteditable="true" data-ph=" Make a note . . . "
style= "height: 300px; overflow: auto"></div>
<div id = "content2">
<div id= "tcontent2" contenteditable="true" data-ph= " Make a note . . . "
style= "height: 300px; overflow: auto"></div>
</div>
And this is my Javascript:
window.addEventListener('load', onLoad); function onLoad() {
checkEdits();
}
function checkEdits() {
if(localStorage.userEdits!=null) {
document.getElementById("tcontent", "tcontent2").innerHTML += localStorage.userEdits;
}
};
document.onkeyup = function (e) {
e = e || window.event;
console.log(e.keyCode);
saveEdits();
};
function saveEdits() {
var editElem = document.getElementById("tcontent", "tcontent2");
var userVersion = editElem.innerHTML;
localStorage.userEdits = userVersion;
};
Basically this code will only save one (the content I place first into the getElementbyId). Isn't there a way to save both of the 'content's?
I've been playing around with all my little knowledge of javascript I have but can't seem to see what I'm doing wrong or what I should be doing here.
Much thanks for any and all help.
document.getElementById is a method that only takes one element's id. You are currently trying to pass two strings to the method. That will not work.
Please refer to the documentation here: https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
Also, you must assign the innerHTML of each element individually to each piece of saved content in localStorage.
Granted that you are fairly new to the Language I do not want to overcomplicate the answer for you. With that said, please find below your code with a few modifications to be able to save both pieces in localStorage respectively:
window.addEventListener('load', onLoad); function onLoad() {
checkEdits();
}
function checkEdits() {
if(localStorage.userEdits1!=null) {
document.getElementById("tcontent").innerHTML = localStorage.userEdits1;
}
if(localStorage.userEdits2!=null) {
document.getElementById("tcontent2").innerHTML = localStorage.userEdits2;
}
};
document.onkeyup = function (e) {
e = e || window.event;
console.log(e.keyCode);
saveEdits();
};
function saveEdits() {
var editElem1 = document.getElementById("tcontent");
var editElem2 = document.getElementById("tcontent2");
localStorage.userEdits1 = editElem1.innerHTML;
localStorage.userEdits2 = editElem2.innerHTML;
};

Find specific div with RegEx and print content

I'm trying to pull some text from an external website using this script.
It works perfectly, but it gets the entire page. I want to take only the content inside a specific div with the class 'content'. The entire page is put inside the variable 'data', and then this function is created to strip some tags:
function filterData(data){
data = data.replace(/<?\/body[^>]*>/g,'');
data = data.replace(/[\r|\n]+/g,'');
data = data.replace(/<--[\S\s]*?-->/g,'');
data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g,'');
data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g,'');
data = data.replace(/<script.*\/>/,'');
return data;
}
How would I go about finding the div with the class 'content' and only viewing the content inside that?
UPDATE: Sorry about using RegExes — can you help me to get the content without using RegEx? So, this is my HTML file:
erg
<div id="target" style="width:200px;height:500px;"></div>
<div id="code" style="width:200px;height:200px;"></div>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script>
$(document).ready(function(){
var container = $('#target');
$('.ajaxtrigger').click(function(){
doAjax($(this).attr('href'));
return false;
});
function doAjax(url){
if(url.match('^http')){
$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(url)+
"%22&format=xml'&callback=?",
function(data){
if(data.results[0]){
var tree = string2dom(data.results[0]);
container.html($("div.content", tree.doc));tree.destroy();
} else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg);
}
}
);
} else {
$('#target').load(url);
}
}
function filterData(data){
return tree;
}
});
</script>
Try something like this:
var matches = data.match(/<div class="content">([^<]*)<\/div>/);
if (matches)
return matches[1]; // div content
try this:
<div\b[^>]*class="content"[^>]*>([\s\S]*?)<\/div>
Here try this :
<div[^>]*?class='content'[^>]*?>(.*?)</div>
Captured reference /1 will have your content. Although you shouldn't be doing this with regexes :)
this may help you:
var divtxt = match(/<div[^>]*class="content"[^>]>.*<\/div>/);
but it may stop at the wrong .
you should use jquery or prototype to make it a dom-object and use selectors to find the right div.
using jquery you would do something like:
var divtxt = $(data).find(".content").first().html();
remember to load the jquery library first.

Categories