simple hover and hover out issue in javascript - javascript

I am trying to create hover and hover out via javascript.
I have
test.prototype.build = function(){
other codes...
link.href = '#';
link.innerHTML += 'test'
link.onmouseover = hover
link.onmouseout = hoverOut
other codes...
}
function hover(){
var div = document.createElement('div');
div.class='testDiv';
div.innerHTML = 'test';
$(this).prepend(div);
}
function hoverOut(){
var div = document.getElementsByClassName('testDiv');
div.style.display='none';
}
My task is to create a hover and hover out function. My problem is I am not sure how to hide the testDiv when the user hover out of the link.
getElementsByClassName doesn't seem to work in my case. Are there better way to do this in javascript? Thanks a lot!

document.getElementsByClassName('testDiv') returns an collection, not a single object, but you can probably just use this to refer to the current object. Since you showed some jQuery in your original code, I assume that is OK here.
function hoverOut(){
$(this).find(".testDiv").hide();
}
or, in plain javascript, it could be:
function hoverOut(){
var elems = this.getElementsByClassName("testDiv");
for (var i = 0; i < elems.length; i++) {
elems[i].style.display = "none";
}
}
Your hover and hoverOut code don't match though because you're creating a new div on hover every time in hover and then only hiding it in hoverOut so they will accumulate.
If you want to remove the div you added in hoverOut(), you can do that like this:
function hoverOut(){
$(this).find(".testDiv").remove();
}
or in plain javascript:
function hoverOut(){
var elems = this.getElementsByClassName("testDiv");
for (var i = 0; i < elems.length; i++) {
elems[i].parentNode.removeChild(elems[i]);
}
}

Related

Toggle is-visible Class to Div Next to Trigger Element (Plain JS)

This is supposed to be a very simple dropdown FAQ system, I know how to do this in jQuery but I want to learn plain JS.
I just want the individual clicked triggers to toggle the is-visible class to the content divs next to the clicked trigger. Like $(this).next addClass — just in JS.
I've really tried to search for this issue but 90% that shows up is how to do it in jQuery :-p
https://jsfiddle.net/48ea3ruz/
var allTriggers = document.querySelectorAll('.faq-trigger');
for (var i = 0; i < allTriggers.length; i++) {
// access to individual triggers:
var trigger = allTriggers[i];
}
var allContent = document.querySelectorAll('.faq-content');
for (var i = 0; i < allContent.length; i++) {
// access to individual content divs:
var content = allContent[i];
}
// I don't know how to target the faq-content div next to the clicked faq-trigger
this.addEventListener('click', function() {
content.classList.toggle('is-visible');
});
Would really appreciate some advice! :-)
Use nextSibling, when you are iterating .faq-trigger
var allTriggers = document.querySelectorAll('.faq-trigger');
for (var i = 0; i < allTriggers.length; i++) {
allTriggers[i].addEventListener('click', function() {
this.nextSibling.classList.toggle('is-visible');
});
}
nextSibling will also consider text-nodes, try nextElementSibling also
var allTriggers = document.querySelectorAll('.faq-trigger');
for (var i = 0; i < allTriggers.length; i++) {
allTriggers[i].addEventListener('click', function() {
this.nextElementSibling.classList.toggle('is-visible');
});
}

Create element for each div with a particular class

I have a couple of divs with a "isVideo" class. I can successfully attach a click event with a for loop, but I also need to create a span within each div. This is what I have:
var videos = document.getElementsByClassName("isVideo");
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener('click', playVideo, false);
var playBtn = videos[i].createElement("span");
playBtn.appendChild(videos[i]);
}
codepen: http://codepen.io/garethj/pen/bpxVKX
You are appending div inside span. You need to append spanElement inside divElement
var videos = document.getElementsByClassName("isVideo");
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener('click', playVideo, false);
var playBtn = document.createElement("span");
videos[i].appendChild(playBtn);
}
Edit: Also change videos[i].createElement to document.createElement as videos[i] does not have method createElement
Codepen Demo
It should be done in the opposite way.
Replace
playBtn.appendChild(videos[i]);
with
videos[i].appendChild(playBtn);

Can you use "this" attribute on onclick of an HTML tag?

Can you use the this tag for the onclick on an HTML tag?
Here's my JS code...
function changeImage() {
this/*<-- right there <--*/.src=a;
}
document.getElementsByTagName('img').onclick = function(){
changeImage();
} ;
Am I doing something wrong?
Use it this way...
function changeImage(curr) {
console.log(curr.src);
}
document.getElementsByTagName('img').onclick = function(){
changeImage(this);
} ;
You could use the .call() method to invoke the function with the context of this.
In this case, you would use:
changeImage.call(this)
Example Here
function changeImage() {
this.src = 'http://placehold.it/200/f00';
}
document.getElementsByTagName('img')[0].onclick = function(){
changeImage.call(this);
};
As a side note, getElementsByTagName returns a live HTMLCollection of elements. You need to apply the onclick handler to an element within that collection.
If you want to apply the event listener to the collection of elements, you iterate through them and add event listeners like this:
Updated Example
function changeImage() {
this.src = 'http://placehold.it/200/f00';
}
Array.prototype.forEach.call(document.getElementsByTagName('img'), function(el, i) {
el.addEventListener('click', changeImage);
});
Or you could simplify it:
Example Here
Array.prototype.forEach.call(document.getElementsByTagName('img'), function(el, i) {
el.addEventListener('click', function () {
this.src = 'http://placehold.it/200/f00';
});
});
You are doing two things wrong.
You are assigning the event handler to a NodeList instead of to an element (or set of elements)
You are calling changeImage without any context (so this will be undefined or window depending on if you are in strict mode or now).
A fixed version would look like this:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].onclick = function () {
changeImage.call(this);
};
}
But a tidier version would skip the anonymous function that does nothing except call another function:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].onclick = changeImage;
}
And modern code would use addEventListener.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].addEventListener('click', changeImage);
}
However, images are not interactive controls. You can't (by default) focus them, so this approach would make them inaccessible to people who didn't use a pointing device. Better to use controls that are designed for interaction in the first place.
Generally, this should be a plain button. You can use CSS to remove the default padding / border / background.
If you can't put a button in your plain HTML, you can add it with JS.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var image = images[i];
var button = document.createElement('button');
button.type = "button";
image.parentNode.replaceChild(button, image);
button.appendChild(image);
button.addEventListener('click', changeImage);
}
function changeImage(event) {
this.firstChild.src = a;
}

Call <a> tag from css into javascript function

I am using this changing color script by j08691:
function flash() {
var text = document.getElementById('foo');
text.style.color = (text.style.color=='red') ? 'green':'red';
}
var clr = setInterval(flash, 1000);
I want to call the <body> tag and <a> tag from the CSS not an id.
For the <body> tag I did this and it works:
function flash() {
var text = document.body;
text.style.color = (text.style.color=='black') ? 'white':'black';
}
var clr = setInterval(flash, 1);
But it isn't working with the <a> tag. I tried variations like:
var els = document.getElementsByTagName('a');
var links = document.getElementsByTagName('a');
Instead of var text = document.getElementById('a'); and replacing text.style.color with links[i].style.color or links.style.color but I'm not quite sure what I'm doing there.
I want to change the colors of all links at once.
You are on the right track - getElementsByTagName returns a collection, so just loop through the collection:
function flash() {
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].style.color = (links[i].style.color=='black') ? 'white':'black';
}
}
setInterval(flash, 1000);
jsFiddle here
Also note that setInterval takes milliseconds, so setInterval(x, 1) isn't advised.
Are you trying to access the a tags in the html? and then apply some css to each via your function?
Using the jquery library
$("a").each(function(){
//do something with the element here like your function. $(this).stuff;
});

JavaScript - Toggle function

Im trying to hide/show a JS function I have defined in a chrome extension.
What I have so far:
The span classes I am trying to hide are label:
dspan.className = "cExtension";
//Create toggle button:
function createToggleButton(){
var toggleButton = document.createElement("button");
toggleButton.innerHTML = "Toggle Overlay";
toggleButton.id = "Toggle"
var header = document.getElementById("header");
header.appendChild(toggleButton);
toggleExtension();
}
// find all spans and toggle display:
function toggleExtension(){
var spans = document.getElementsByTagName('span');
var toggle = function() {
for (var i = 0, l = spans.length; i < l; i++) {
if (spans[i].getAttribute('class') == 'cExtension')
if (spans[i].style.display == 'none') spans[i].style.display = '';
else spans[i].style.display = 'none';
}
}
document.getElementById('Toggle').onclick = toggle;
}
The button shows on the header, however it is unclickable. If I change document.getElementById('Toggle').onclick = toggle; to document.getElementById('Toggle').onclick = alert{"Hello"); the alert is triggered on page load on not onclick. I am trying to get this done in pure JS. Where am I going wrong?
First of all, document.getElementById("Toggle").onclick = alert("Hello"); will set the onclick event to whatever the alert function returns, not the alert function itself. So the alert function happens at page load so it can figure out what to return. So you could do this: document.getElementById("Toggle").onclick = function(){alert("Hello");}; and that might work.
Edit: Scratch everything that was here: I missed that toggle variable set to a function in toggleExtension.
I haven't tested all this so I can't guarantee that it'll all work in your specific case.
if visible is set remove it, otherwise add it
div.classList.toggle("visible");
add/remove visible, depending on test conditional, i less than 10
div.classList.toggle("visible", i < 10 );
Make sure browser support: http://caniuse.com/#feat=classlist
Why not use jQuery?
It will do all hard job for you.
http://api.jquery.com/toggle/
Cheers!

Categories