Why the event doesn't execute? - javascript

Hey guys could anyone explain why the event doesn't execute?
The debugger doesn't give any error at all!
Thank you in advance
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<button class="boton">prueba</button>
<body>
<script type="text/javascript">
var elemento= document.getElementsByClassName("boton")
elemento.onclick=function(){
alert("hola");
};
debugger;
</script>
</body>
</html>

The DOM method document.getElementsByClassName() returns an array. You must loop through the array items before assigning the onclick handler:
var elemento = document.getElementsByClassName("boton")
for (var i = 0; i < elemento.length; i++) {
elemento[i].onclick = function() {
alert("hola");
};
}
debugger;
<button class="boton">prueba</button>
Alternatively, if you are selecting only one element, you can use document.querySelector():
var elemento = document.querySelector(".boton");
elemento.onclick = function() {
alert("hola");
};
debugger;
<button class="boton">prueba</button>

Related

How to change event execution order?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Close window</title>
</head>
<body>
<button id="abc" onclick="temp1()">button</button>
<script type="text/javascript">
function temp1() {
alert("temp1");
};
function temp2() {
alert("temp2");
}
document.getElementById("abc").addEventListener("click", temp2, false);
</script>
</body>
</html>
but I want to show "temp2" first, and then show "temp1"
Is that possible? or the event execution order depends on the browser so I can't change it?
thanks for help!!
Please review this one:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Close window</title>
</head>
<body>
<!-- here is your first AddEventlistener-->
<button id="abc" onclick="temp1()">button</button>
<script type="text/javascript">
function temp1() {
alert("temp1");
};
function temp2() {
alert("temp2");
}
/*then here is your second AddEventlistener*/
var d = document.getElementById("abc");
d.addEventListener("click", temp2, false);
/*javascript will execute it in order
if you want to change the order. remove first EventListener then register new one after. something like this:
*/
//remove listener
d.onclick = null;
//register new
d.addEventListener('click', temp1);
</script>
</body>
</html>
There are a couple of ways in which you can guarantee the order here:
document.getElementById("abc").addEvenListener("click", function() {
temp2();
temp1();
}, false);
Another option would be:
function temp2() {
alert();
temp1(); // call temp1 at the end of temp2
}
document.getElementById("abc").addEventListener("click", temp2, false);

Convert a HTML Collection to Javascript Array?

I am a newbie, trying to learn w3c-dom, html-dom, just went through this DOM-Introduction
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DOM</title>
</head>
<body>
<script type="text/javascript">
var getByTag = function(selector) {
// FIXME: Do more conditions -- Come Up with more non-verbose regex condition
return /\w/i.test(selector) ? document.getElementsByTagName(selector) : null;
}
var isHTMLCollection = function(data) {
return data.toString() === '[object HTMLCollection]';
}
var toArray = function(c) {
return Array.prototype.slice.call(c);
}
var getAllPs = getByTag('p');
console.log(isHTMLCollection(getAllPs), 'isHTMLCollection');
console.log(Array.isArray(getAllPs), 'isArray-1');
console.log(getAllPs, 'getAllPs');
var _arrayLike = toArray(getAllPs);
console.log(Array.isArray(_arrayLike), 'isArray-2');
console.log(_arrayLike.length, 'Array.length');
</script>
<p id="p1">
First Para
</p>
<p id="p2">
Second Para
</p>
</body>
</html>
While logging this on console, i got just an empty array, when i tried to convert the HTMLCollection to Array.
Note: Tried using for-loop also.
Attached the console output,
Yes, adding
document.addEventListener('DOMContentLoaded', function() { //rest of the code });
fixes the issue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DOM</title>
</head>
<body>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var getByTag = function(selector) {
// FIXME: Do more conditions -- Come Up with more non-verbose regex condition
return /\w/i.test(selector) ? document.getElementsByTagName(selector) : null;
}
var isHTMLCollection = function(data) {
return data.toString() === '[object HTMLCollection]';
}
var toArray = function(c) {
return Array.prototype.slice.call(c);
}
var getAllPs = getByTag('p');
console.log(isHTMLCollection(getAllPs), 'isHTMLCollection');
console.log(Array.isArray(getAllPs), 'isArray-1');
console.log(getAllPs, 'getAllPs');
var _arrayLike = toArray(getAllPs);
console.log(Array.isArray(_arrayLike), 'isArray-2');
console.log(_arrayLike.length, 'Array.length');
});
</script>
<p id="p1">
First Para
</p>
<p id="p2">
Second Para
</p>
</body>
</html>
Note: Problem with chrome console is, array values are evaluated on asynchronously.
Thanks to #somethinghere & #trincot.

How to program a button to change stylesheets with javascript

Please note that I am not using classes. I haven't found an answer for this SPECIFIC question.
Using javascript, how can I program a button to change the stylesheet each time the button is clicked?
I've tried different if, else if and else, but when I try them, it breaks the code (ie, it will change the color to blue if red, but not back again).
It works with 2 buttons, but getting it to change each time a single button is clicked seems to be eluding me. I got feed up and programmed a second button to change it back.
This works for 2 buttons:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>"Your Title Here"</title>
<link id="um" rel="stylesheet" href="stylesheet1.css">
<style>
</style>
</head>
<body>
<p>booga</p>
<button id="x" onclick="myFunction()">blue</button>
<button id="x1" onclick="myFunction1()">red</button>
<script>
function myFunction() {
if (document.getElementById("um").href = "stylesheet1.css"){
document.getElementById("um").href = "stylesheet2.css"}
}
function myFunction1() {
if (document.getElementById("um").href = "stylesheet2.css"){
document.getElementById("um").href = "stylesheet1.css"}
}
</script>
</body>
I would like to be able to get rid of the second button and second function and have it all with one button.
EDIT...
I tried this, and it failed.
function myFunction() {
if (document.getElementById("um").href == "stylesheet1.css")
{document.getElementById("um").href = "stylesheet2.css"};
else {document.getElementById("um").href = "stylesheet1.css"}
}
Make sure you're using == instead of = for your comparisons!
if (document.getElementById("um").href == "stylesheet1.css")
etc
Try this:
<button id="x" onclick="myFunction()">Change</button>
<script>
function myFunction() {
var link = document.getElementById("um");
var segments = link.href.split('/');
var currentStyle = segments[segments.length - 1];
var style = (currentStyle == 'stylesheet1.css') ? 'stylesheet2'
: 'stylesheet1';
document.getElementById("um").href = style + ".css"
}
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>"Your Title Here"</title>
<link id="um" rel="stylesheet" href="stylesheet1.css">
</head>
<body>
<p>booga</p>
<button onclick="myFunction('um','stylesheet1.css', 'stylesheet2.css')">swap</button>
<script>
function myFunction(id,a,b) {
var el = document.getElementById(id);
var hrefStr;
if(~el.href.indexOf(a)) {
hrefStr = el.href.replace(a, b);
el.href = hrefStr;
} else {
hrefStr = el.href.replace(b, a);
el.href = hrefStr;
}
}
</script>
</body>
</html>

Why can I call function which is in a shadow dom?

I created a custom element called "memory-box" like the below code.
Please pay attention to the function "logthis" which is in "memory-box-template".
memory-box.html
<template id="memory-box-template">
<input id="memory-box" type="form" />
<input type="button" id="testbutton" />
<script type="text/javascript">
function logthis(me){
console.log(me);
}
</script>
</template>
<script type="text/javascript">
(function() {
var thisDoc = document.currentScript.ownerDocument;
var storage = localStorage;
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var temp = thisDoc.querySelector('#memory-box-template');
var con = document.importNode(temp.content, true);
this.createShadowRoot().appendChild(con);
var input = this.querySelector('::shadow #memory-box');
var data = storage.getItem(this.id);
input.value = data;
input.addEventListener('input', saveData.bind(input, this.id));
}
},
});
document.registerElement('memory-box', {
prototype: proto
});
function saveData(id, e) {
storage.setItem(id, this.value);
}
})();
</script>
Now, I uses the custom element "memory-box" like the below code.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="import" href="/html/memory-box.html">
</head>
<body>
<div><memory-box id="memory1"></memory-box></div>
<div><memory-box id="memory2"></memory-box></div>
<div><memory-box id="memory3"></memory-box></div>
<div><memory-box id="memory4"></memory-box></div>
</body>
<script type="text/javascript">
logthis(this);
</script>
</html>
As you can see, I putted a script in the index.html and called the function "logthis" just because I was curious. And no error occurred.
Why?
The function "logthis" is in each shadow doms. It's supposed not able to be called outside the shadow dom, I think.
As explained here, while the HTML within Shadow DOM is encapsulated, any JavaScript is NOT -- it is in the global scope, unless you utilize specific javascript techniques (namescaping, IIFE) to do so.
Hope this helps,
Jonathan Dodd

Javascript for loop for text substitution

I try to use for loop as the substitution of list all
function init(){
new dEdit($('editBox'));
new dEdit($('editBox2'));
new dEdit($('editBox3'));
}
relaced by
function init(){
for(var i = 0; i < 1000; i++){
new dEdit($('editBox'+i));
}
}
but it seems it doesn't work for me. How to correct it?
Below is fully working code without "for loop":
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title> New Document </title>
<meta name="title" content="" />
<meta name="author" content="0xs.cn" />
<meta name="subject" content="" />
<meta name="language" content="zh-cn" />
<meta name="keywords" content="" />
<style type="text/css" >
/* default css rule */
body { font: 12px "Verdana"; }
</style>
<script type="text/javascript" >
// shortcut
function $(s){
return typeof s == 'object'?s:document.getElementById(s);
}
var dEdit = function(el){
var me = this;
this.save = function (txt){
el.innerHTML = txt;
};
this.edit = function (e){
var e = e || event;
var target = e.target || e.srcElement;
if(target.tagName.toLowerCase() == 'input'){
return;
}
var ipt = document.createElement('input');
ipt.value = target.innerHTML;
ipt.onkeydown = function(){
if((arguments[0]||event).keyCode==13){
me.save(this.value);
}
};
ipt.onblur = function(){
me.save(this.value);
};
target.innerHTML = '';
target.appendChild(ipt);
ipt.focus();
};
el.onclick = this.edit;
};
function init(){
new dEdit($('editBox'));
new dEdit($('editBox2'));
new dEdit($('editBox3'));
}
window.onload = init;
</script>
</head>
<body>
<span id="editBox">This is sample text.</span> <br/><br/>
<span id="editBox2">This is sample text 222.</span> <br/><br/>
<span id="editBox3">This is sample text 333.</span>
</body>
</html>
Change the ids on your span tags to "editBox0", "editBox1" and "editBox2". Also, you posted this exact same question not 20-30 minutes ago and someone gave you the correct answer then too.
You need to add # prefix for ID selectors. Change your code to:
function init(){
for(var i = 0; i < 1000; i++){
new dEdit($('#editBox'+i));
}
}
Among other issues like what happens when you call dEdit(...) on an empty jQuery object...
You need a # prefix to select an ID:
$('#editBox2')
Your loop goes from 0 to 1000 and editBoxN is not a valid ID selector, so you end with
new dEdit($('editBox0'));
new dEdit($('editBox1'));
new dEdit($('editBox2'));
...
change first editBox ID, the loop variable and add a hash to the jquery selector to match the IDs
function init(){
for(var i = 1; i < 1000; i++){
new dEdit($('#editBox'+i));
}
}
The problem is the init is throwing an expection on the first value, since 'editBox0' does not exist. To fix this you can wrap each loop iteration in a try/catch.
e.g.
function init(){
for(var i = 0; i < 1000; i++){
try {
new dEdit($('editBox'+i));
} catch (e) {}
}
}
This way, if an id is undefined, the script still runs. Also, you should change <span id="editBox"> for <span id="editBox0"> or <span id="editBox1"> if you intend to have it assigned on the loop.

Categories