Getting the contents of a div using on-click functions - javascript

I am currently trying to implement a "button" of sorts using javascript. When a user clicks on the div, the div background should change colors, and there should be a pop up listing the device number. I am planning on using the number to redirect the client later. But right now, I can't get the clicking event to register. I had the event working correctly for a bit, but the value was always the final value of 'i'. My webpage also has JQuery in it.
Here's a JSFiddle and my relevant code.
http://jsfiddle.net/G3ADG/9/
HTML Structure:
<div class="device" id="device1" value="1">
<div class="device-name" id="deviceName1">Name1</div>
</div>
<div class="device" id="device2" value="2">
<div class="device-name" id="deviceName2">Name2</div>
</div>
<div class="device" id="device3" value="3">
<div class="device-name" id="deviceName3">Name3</div>
</div>
Javascript:
(function() {
var devices = document.getElementsByClassName("device");
for (var i = 0; i < devices.length; i++) {
devices[i].addEventListener("click", function () {
alert(i);
this.style.backgroundColor = "#000000";
})
}
})();
Any help or input is appreciated.
EDIT: Fixed the ClassName call. The alert returned is still wrong though.

If you are already using jQuery - What you are trying can be done with this -
$('.device').on('click',function(){
$(this).css('background-color','red');
})
Demo ---> http://jsfiddle.net/G3ADG/8/

Check this fiddle:
You just needed a closure to attach events
(function () {
var devices = document.getElementsByClassName("device");
for (var i = 0; i < devices.length; i++) {
(function (i) {
devices[i].addEventListener("click", function () {
alert(i);
this.style.backgroundColor = "#000000";
})
})(i);
}
})();

Instead of running a for loop, just run $('.device').each(). I also added an alert to get each div.device's value. See here: http://jsfiddle.net/G3ADG/10/
Edit: I did it with bind instead of an on click because that mirrored how he was doing it in plain JS. pXL's solution using on works just as well if you are not dynamically adding div.device.

Related

JavaScript For Loop not returning anything (not running)?

Ok so, I've got this for loop in a script tag on my EJS page. The current code looks like this:
<script async>
var removeCartItemButtons = document.getElementsByClassName('btn-danger')
console.log(removeCartItemButtons)
var i;
for (i = 0; i < removeCartItemButtons.length; i++){
console.log('elem')
var button = removeCartItemButtons[i]
button.addEventListener('click', function() {
console.log('clicked')
})
}
</script>
The console.log for the removeCartItemButtons works but the console.log('elem') doesn't run. There are no errors in my cmd nor on the developer tools. I've looked online at different forums to find people doing similar things to me and their's work fine.
I've tried multiple things, and an extra notice is that this is inside the html file and not external.
The end goal of this for loop is to loop through every element with class 'btn-danger' and log when they are clicked.
Any help would be amazing!
try running document.getElementsByClassName('btn-danger') in the console.
Additional tip: there is a for of loop in js
check this: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/for...of
basically:
for(let button of removeCartItemButtons) {
button.addListener
}
I tried this code in Codepen and it worked. I rewrite your code but technically, just used a different syntax. "async" in your script tag can cause the problem, I can't be sure.
var buttons = document.querySelectorAll('.btn-danger');
[...buttons].forEach(button => {
console.log('elem')
button.addEventListener('click', function() {
console.log('clicked')
})
})
There must be an issue with your HTML code. Run the snippet below, it's working fine
var removeCartItemButtons = document.getElementsByClassName('btn-danger')
console.log(removeCartItemButtons)
var i;
for (i = 0; i < removeCartItemButtons.length; i++) {
console.log('elem')
var button = removeCartItemButtons[i]
button.addEventListener('click', function() {
console.log('clicked');
alert('clicked');
})
}
<button class='btn-danger'>Button</button>
<br/>
<button class='btn-danger'>Button</button>
<br/>
<button class='btn-danger'>Button</button>
<br/>
<button class='btn-danger'>Button</button>
removeCartItemButtons.length is 0 because when the snippet ran the DOM was not fully loaded.
Remove async and put your script at the end of your html.
Another option is to use an EventListener like onload to make sure your buttons exist before changing them.

parse html textfield to javascript

Hello I have a question and I've been googling it before asking to you guys and I can't find the solution. I would like to have the data-id="video" added in a textbox so that I can change it without changing the source file everytime.
<div class="youtube-container"><div class="youtube-player" data-id="VIDEO"></div></div>
Is it possible that I can change the "VIDEO" with a textfield??
I have a javascript that loads the video so that I can just type in a video id.
Hope someone can help me with this.
Below is the code that calls for the video id.
(function() {
var v = document.getElementsByClassName("youtube-player");
for (var n = 0; n < v.length; n++) {
var p = document.createElement("div");
p.innerHTML = labnolThumb(v[n].dataset.id);
p.onclick = labnolIframe;
v[n].appendChild(p);
}
I forgot to post this the first time.
For parse:
$(".youtube-player").data("id")
For change content:
$(".youtube-player").data("id","NEW CONTENT")
how are you want to change it - on your choice, with select or textfield
You must add input
<input type="text">
And this jQuery code
$('input').on('change', function() {
$('.youtube-player').data('id', $(this).val());
});

Event target should be anchor but is image instead

I am working on a dialog script in Vanilla JS. I ran into a problem with the click event on the video image. Even tough the image is surrounded with an anchor tag it shows the image as the event.target on the "trigger-dialog-open" event.
Here is the HMTL:
<a class="trigger-dialog--open thumbnail" data-dialog-id="dialog-video" href="javascript:;">
<figure>
<img src="http://i.ytimg.com/vi/id/sddefault.jpg" alt="" />
</figure>
</a>
And this is the event in JS:
var openTriggers = document.getElementsByClassName('trigger-dialog--open');
for (var i = 0; i < openTriggers.length; i++) {
openTriggers[i].addEventListener("click", function (event) {
this.openDialog(event.target.getAttribute('data-dialog-id'));
}.bind(this), false);
}
The event handler wants to know the dialog-id from the anchors data attribute. It can't be found because it thinks the image is the event.target, not the actual anchor. How can I correct this? Thanks!
Use event.currentTarget. The event.target is supposed to be the img element since that is what the user has clicked on. The click then bubbles up through the image's containers. event.currentTarget gives you the element that the click handler was actually bound to.
(Or if you didn't bind this to some other object you could use this within the click handler and it should also be the current target.)
I have a few questions is the var openTriggers supposed to be a part of a module hash? Because if it's global then you don't use a this, you only add a this, if it's referencing a variable that the function is also contained in. For example:
var aThing = {
openTriggers: document.getElementsByClassName('trigger-dialog--open'),
openModal: null,
openDialog: function(clickedThingAttr){
if(this.openModal !== null){
this.openModal.style.display = 'none';
}else{
this.openModal = document.getElementById(clickedThingAttr);
}
this.openModal = document.getElementById(clickedThingAttr);
this.openModal.style.display = 'block';
},
setEventListenersNStuff: function(){
for (var i = 0, n = this.openTriggers.length;i < n; i++) {
this.openTriggers[i].addEventListener("click", function (event) {
this.openDialog(event.target.getAttribute('data-dialog-id'));
});
};
}
};//end of aThing hash object
aThing.setEventListenersNStuff();
There are a few issues here:
1. why are you using .bind I think that is a jQuery thing, you want to pass a string to another function when an object is clicked, there no need for binding at all.
2. Also make sure that if you want to do something like open a modal, there is no need to call another method unless it's kinda complex.
3. What about other potential dialogs, it seems that when a .trigger-dialog--open is clicked you're just showing that one one modal with the embedded id, but what about others? Make sure all modals are closed before you open a new one, unless you want to have like 10 modals are open.
A thing to note: I added the line var i = 0, n = openTriggers.length;i < n; i++, now in this case it's silly optimization, and I heard for modern browsers this doesn't apply, but to explain why I added it, is because i < openTriggers.length would count and integrate the array N times. (This may be an outdated optmiziation).
If you meant global
Below I added a different set of code, just in case you meant that var openTriggers is global, kinda like you wrote above. Also I used querySelectorAll for this which is like jQuery's $('.thing') selector.
anyhoo, I also added
var openTriggers = document.querySelectorAll('.trigger-dialog--open');
var n = openTriggers.length;
function openDialog(ddId){
for (var i = 0;i < n; i++) {
openTriggers[i].style.display = 'none';
};
document.getElementById(ddId).style.display = 'block';
};
for (var i = 0;i < n; i++) {
openTriggers[i].addEventListener("click", function (event) {
openDialog(event.target.getAttribute('data-dialog-id'));
});
}
}
So for the question of hiding already open modals I would suggest you could either cache the open Dialog within a module, or you could toggle a class, which would be less efficient since it would require an extra DOM search. Additionally you could add a if this.openModal.id === clickedThingAttr to hide if open, that way you got a toggle feature.
Anyways I suggest you read up on this stuff, if you want to use plain JS but would like the features of jQuery: http://blog.romanliutikov.com/post/63383858003/how-to-forget-about-jquery-and-start-using-native
Thank you for your time.
You can use a closure
var openTriggers = document.getElementsByClassName('trigger-dialog--open');
for (var i = 0; i < this.openTriggers.length; i++) {
(function(element) {
element.addEventListener("click", function (event) {
element.openDialog(event.target.getAttribute('data-dialog-id'));
}, false)
})(openTriggers[i]);
}

Javascript changes not seen

I have a jsp file that calls a javascript function in a separate .js file. I have made an amendment to the .js function (added an alert()) and re-run the program. The alert is not called therefore the method is not called. I have renamed the method so that I get an exception but the method is successfully called. I have cleared the cache on Chrome and nothing has changed. I am using IntelliJ + embedded Tomcat.
Can anyone tell me what is going wrong?
<div id="names" style="width: 100%;"><script>myFunc();</script></div>
function myFunc(asString) {
alert("hello");
var s;
for (var i = 0; i < 10; i++) {
s += "helloAgain";
}
return s;
}
EDIT: Ok, I've found the issue. Using Firebug, I can now debug into the writePax function but... there is no alert() function. So the version I have amended is not the version being used in the app - even though the version in my exploded war has the amended version (with the alert()). Anyone know why, even after clearing my cache, all browsers are using an old .js file?
I don't know what you are trying to achieve, but this will work
<div id="names" style="width: 100%;" onClick="myFunc()">Click Me</div>
You can try it out here http://jsfiddle.net/6rQpE/
myFunc should be called as long as you put the JavaScript before the HTML.
JavaScript functions do have return values, but that's not how you insert text into the document. It has to be done entirely within JavaScript or with a framework to make it easier.
If you were using jQuery you could write something like
<script>
var myFunc = function() {
alert("Surely I was clicked");
var htmlOut = '';
for (var i = 0; i < 10; i++) { htmlOut += "hello again<br>"; }
// selects the element with "names" as the id
// and changes the html to the value of htmlOut
$("#names").html(htmlOut);
};
// this is a jquery convention, it will execute this code when the html is done loading.
$(function(){
$("button").click(myFunc);
});
</script>
Then you would put
<button>Click me</button>
somewhere in your HTML.
If you are running this as it shows in your example above I don't think you can call the function before declaring it in the file.
Example:
<div id="names" style="width: 100%;"><script>myFunc();</script></div>
function myFunc(asString) {
alert("hello");
var s;
for (var i = 0; i < 10; i++) {
s += "helloAgain";
}
return s;
}
Will not work.....
function myFunc(asString) {
alert("hello");
var s;
for (var i = 0; i < 10; i++) {
s += "helloAgain";
}
return s;
}
<div id="names" style="width: 100%;"><script>myFunc();</script></div>
Will.....
Hope that helps
My app is using a static server to serve files and it's configured to use a static version of my .js file. I've pointed my app to use local files and it is now displaying the alert().

Passing a variable into a DOM function in Javascript

I took this example from w3schools and modify it to this. The code below is not working.
What I intend to do is hide the div with id "demo1". It is not working. What is the problem?
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction(div_id)
{
//here the div_id variable seems to unparsable by the DOM event
document.getElementById(div_id).innerHTML = hello;
}
</script>
</head>
<body>
<p>Click the button to trigger a function.</p>
<button onclick="myFunction('demo1')">Click me</button>
<div id="demo1"></div>
<div id="demo2"></div>
</body>
</html>
The variable hello is not defined. You were probably looking to set the innerHTML as a String:
function myFunction(div_id) {
document.getElementById(div_id).innerHTML = "hello";
// -----------------------------------------^-----^
}
DEMO: http://jsfiddle.net/uzuKp/1/
Even though you took an example from W3Schools and modified it, I'd suggest binding events separate from the HTML and storing associated data in data-* attributes. In your example, it can be as something like this:
<p>Click the button to trigger a function.</p>
<button data-div-id="demo1">Click me</button>
<button data-div-id="demo2">Click me</button>
<button data-div-id="demo1">Click me</button>
<div id="demo1">demo1</div>
<div id="demo2">demo2</div>
And the JS:
function clickHandler() {
var targetDivId, targetDiv;
targetDivId = this.getAttribute("data-div-id");
targetDiv = document.getElementById(targetDivId);
targetDiv.innerHTML = "Hello" + new Date().getTime();
}
function loadHandler() {
var buttons, i, j, cur;
buttons = document.getElementsByTagName("button");
for (i = 0, j = buttons.length; i < j; i++) {
cur = buttons[i];
cur.onclick = clickHandler;
}
}
window.onload = loadHandler;
DEMO: http://jsfiddle.net/3K4RD/
Although I would also suggest looking at the following article to see different ways to bind events: addEventListener vs onclick
One final suggestion I have is to not set the innerHTML property. You may have a simple example here, but it's usually a better idea to use DOM methods like appendChild (to add a node) and document.createTextNode (to create text that can be appended). Of course, that would require the contents to be cleared out first, something like:
while (targetDiv.firstChild) {
targetDiv.removeChild(targetDiv.firstChild);
}
targetDiv.appendChild(document.createTextNode("Hello"));
DEMO: http://jsfiddle.net/52Kwe/
You could also store the specific string that needs to be set as the innerHTML as a data-* attribute (especially if it differs between buttons).
UPDATE:
Per your recent edit, the style property is a special property, which is actually a special object with style properties that you need to set. So for your example, you have to set the .style.display value, like:
document.getElementById(div_id).style.display = "none";
document.getElementById(div_id).style.display = 'none';
document.getElementById(div_id).style.visibility= 'hidden';

Categories

Resources