error while changing element in DOM using vannilla JS - javascript

I have create a program to change an element in a HTML while a button is clicked, but it causes an error
<button id='change'>hi</button>
<p id="pp">text</p>
<script>
var myfunction=function(e){
e.preventDefault();
document.getElementById('pp').innerHTML=<p id="pp">change</p>
}
document.getElementById('change').addEventListener('click',myfunction(e))
</script>
codesand box link
https://codesandbox.io/s/bold-waterfall-90e74

you have 2 problems. one is you're passing the return value of myFunction into .addEventListener with the value of e which is not defined. the other is your not setting the .innerHTML correctly. I'm not sure if you can create HTML elements in JavaScript using HTML syntax, but if you can, you're creating another <p> element with the same id. Also, .innerHTML should be a String and all HTML attributes should have double quotes. try this:
document.getElementById('change').addEventListener('click', function (e) {
e.preventDefault();
document.getElementById('pp').innerHTML = "change";
})
<button id="change">hi</button>
<p id="pp">text</p>
You also probably shouldn't create functions with var functionName = function() {...} because it can cause hoisting problems. var is also deprecated and can cause bugs so I would advise to use const and let.

fix this string:
document.getElementById('change').addEventListener('click', myfunction)

You were missing quotes around the innerHTML value.
When calling addEventListener, your EventListener is the function "myfunction". You don't have to call it.
<button id='change'>hi</button>
<p id="pp">text</p>
<script>
var myfunction=function(e){
e.preventDefault();
document.getElementById('pp').innerHTML='<p id="pp">change</p>'
}
document.getElementById('change').addEventListener('click',myfunction)
</script>

Related

How to modify value inside HTML tags by class name

I've been given this string <p><span class='math-tex'>\\( x>0,y>0 \\)</span></p>
And I want to modify the inside value, so it would render with math jax
To be come like this
<p><span class='math-tex'>$$\\( x>0,y>0 \\)$$</span></p>
There are $$ wrapping the value.
I am clueless how to use math jax properly, I think this is the best way to solve from my previous thread -> (How to use math jax?)
But I have no idea how modify the those value when the window load on start
You can use pure javascript for that. See the links for further reading.
<script>
window.addEventListener("load", function(event) {
let elementsArray = document.getElementsByClassName("math-tex");
elementsArray[0].setAttribute("class", "some-other-class-name");
elementsArray[0].innerHtml("some other value");
});
</script>
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute

Parameter passing in JavaScript onclick: this.id versus other attributes

I suspect there is something basic about JavaScript parameter passing that I do not understand.
If I click on this button, I get an 'undefined' message in the alert box.
<button onclick="play_audio(this.src)" src="foo.m4a">▶</button>
If I click on this button, the string value is passed properly:
<button id="foo.m4a" onclick="play_audio(this.id)">▶</button>
Codepen here:
https://codepen.io/anon/pen/JBpMYo
A button does not have a src attribute. However, you can use this.getAttribute('src').
<button src="foo.m4a" onclick="play_audio(this.getAttribute('src'))" >▶</button>
<script>
function play_audio(src){
console.log("Playing "+src);
}
</script>
It is recommended that you usedata-src (you can use any prefix after data-, not necessarily src) and this.dataset.src instead (you can use the data-* attribute to embed custom data) because it will ensure that your code will not clash with HTML Element attributes for future editions of HTML. See the documentation.
<button data-src="foo.m4a" onclick="play_audio(this.dataset.src)" >▶</button>
<script>
function play_audio(src){
console.log("Playing "+src);
}
</script>

How to pass a variable to a function inside JQuery

I have something like this:
for (var i = 1; i <= numPages; i++)
{
buttons.append($("<button onclick='getJSON(i)'>"+i+"</button>"));
}
Now, passing i inside getJSON() function doesn't seem to work.
Any ideas how to solve this?
Other answerers already have described how you can do this.
However, I would recommend another way:
for (var i=1; i<=numPages;i++)
{
$("<button/>")
.addClass('myClass')
.attr('data-my-id', i)
.text(i)
.appendTo(buttons);
}
$(document).on('click', '.myClass', function() {
getJSON($(this).attr('data-my-id'));
});
It will generate the following HTML:
<button class='myClass' data-my-id='1'>1</button>
<button class='myClass' data-my-id='2'>2</button>
<button class='myClass' data-my-id='3'>3</button>
<button class='myClass' data-my-id='4'>4</button>
etc.
Why is this approach better?
Button is now generated using jQuery, but not from a string, which decreases a chance of error
It uses jQuery events instead of onclick attribute
Event delegation for convenient work with dynamically created elements
Element HTML doesn't contain behaviour (event) - it stores data (id)
jQuery is slower than a native JavaScript, but it is important only if we talk about thousands of elements. Otherwise, it is more important that code can be easily written, read and supported.
Also, here is a good article which describes why you shouldn't use onclick attribute`:
jQuery.click() vs onClick
buttons.append($("<button onclick='getJSON("+i+")'>"+i+"</button>"));
You need to concatenate is properly, the way you did for another i
Pass i to the getJSON method as a variable. You have sent it as a string by mistakenly.
for (var i=1;i<=numPages;i++)
{
buttons.append($("<button onclick='getJSON("+i+")'>"+i+"</button>"));
}

Try It Yourself Editor JS

I have created a very simple editor that has been working great. However, I just tried to put JavaScript into it and I can't get it to work.
The code for the editor:
<div id="buttoncontainer">
<input id="button" onclick="update();" type="button" value="Update page">
</div>
<div id="tryitcontainer">
<textarea id="codebox"></textarea>
<iframe id="showpage"></iframe>
</div>
The JavaScript for the editor:
<script>
function update() {
var codeinput = document.getElementById('codebox').value;
window.frames[0].document.body.innerHTML = codeinput;
}
</script>
I just wanted to run some simple JavaScript that changes an image when it is clicked. This code works fine when I run it in a full browser, so I know its the editor thats the problem.
Is there a simple fix for this that I'm missing?
The button is not finding the update() method. You need that function to be globally available:
http://jsfiddle.net/t5swb7w9/1/
UPDATE: I understand now. Internally jQuery basically evals script tags. There's too much going on to be worth replicating yourself... either use a library to append, or eval the code yourself. Just a warning that eval'ing user input is rarely a good thing and is usually a welcome mat for hackers.
window.myScope = {
update: function() {
var div = document.createElement('div'),
codeinput = document.getElementById('codebox').value,
scriptcode = "";
div.innerHTML = codeinput;
Array.prototype.slice.apply(div.querySelectorAll("script")).forEach(function(script) {
scriptcode += ";" + script.innerHTML;
div.removeChild(script);
});
window.frames[0].document.body.appendChild(div);
// hackers love to see user input eval'd like this...
eval(scriptcode);
}
};
And then you would update your button like so:
<input id="button" onclick="myScope.update();" type="button" value="Update page">
Or, even better, use addEventListener and forget the onclick part altogether. I'll let you do that research on your own ;)
JavaScript inserted via innerHTML will not be executed due to security reasons:
HTML5 specifies that a <script> tag inserted via innerHTML should not execute.
from MDN: Element.innerHTML - Security considerations, see also: W3: The applied innerHTML algorithm.
A possible solution using the jQuery method .append() works around that, as it somehow evals the content. But this will still not solve your problem, as the JavaScript code is executed in the current scope.
Here's a test scenario:
function update() {
var codeinput = document.getElementById('codebox').value;
$(window.frames[0].document.body).append(codeinput);
}
Try it here
Try to insert this script:
<script>
alert( document.getElementById('tryitcontainer') );
</script>
and this one:
<p id="test">Test</p>
<script>
window.frames[0].document.getElementById('test').innerHTML = 'updated';
</script>
The first one will return a [object HTMLDivElement] or similar. Here you can see, that you're still in the same scope as the parent frame. The second one will correctly update the content within the iframe. Keep that in mind, when experimenting with those things.
Maybe Executing elements inserted with .innerHTML has some more infos for you.

Setting title attribute with Javascript function

I am trying to find, if I can pass a value on the title attribute of a label element using Javascript?
I have tried the following Javascript code:
function myFunction()
{
return "Hello!";
}
And a piece of HTML code:
<label title="myFunction()">TEST</label>
But, this isn't working. It just show the 'myFunction()' as a text.
Is it possible, what I am trying to do? If yes, what is the correct syntax?
<label id='mylabel'>TEST</label>
<script>
function myFunction() {
return "Hello!";
}
document.getElementById('mylabel').setAttribute('title', myFunction());
</script>
Should do the job. It first selects the label and then sets the attribute.
You can't inline javascript like this.
What you may do is
1) give an id to your label and put this at the end of your body
<script>
document.getElementById('myId').title = myFunction();
</script>
Demonstration
2) if you really want to inline the call, write this at the point where you want your label :
<script>
document.write('<label title="'+myFunction()+'">TEST</label>');
</script>
(this is really not recommended)
Try this way:-
HTML:
<label id="lab">TEST</label>​
JS:
window.onload = function() {
document.getElementById('lab').setAttribute('title','mytitle');
alert(document.getElementById('lab').title);
}​
Refer LIVE DEMO
I got this! If you are using angular you can use this data Binding and call the function
<label title="{{myFunction()}}">TEST</label>

Categories