how to pass multi-array arguments to jquery for loop - javascript

I want to show my overlays when hovering over items.
This the code:
<div class="item" id="item-1">
<div class="overlay" id="overlay-1"></div>
</div>
<div class="item" id="item-2">
<div class="overlay" id="overlay-2"></div>
</div>
var items=["#item-1","#item-2"];
var overlays=["#overlay-1","#overlay-2"];
for (var i = 0; i < products.length; i++) {
$(items[i]).hover(
function(){$(overlays[i]).css("visibility", "visible");},
function(){$(overlays[i]).css("visibility", "hidden");});
}
however, it doesn't work...
it seams that overlays[i] can't be recognized...
why?

I would do something like this
$(".item").hover(function(){
$(this).find(".overlay").show();
});

This seems like it is a scoping issue where the overlays you are trying to select are out of scope.
You could eliminate the need to explicitly loop over the items altogether by just apply the hover to the "item" class and the hide/show logic to the "overlay" class. Additionally, to hide and show items, the jQuery friendly pattern is to use the hide and show methods.
$('div.item').hover(function(){
var overlay = $(this).children('div.overlay');
overlay.hide();
});
overlay.hide();
},
function(){
var overlay = $(this).children('div.overlay');
overlay.show();
});
With out knowing all of the details, you should know that this approach could produce some unwanted flickering.

It's a closure issue. By the time the hover in/out functions actually run, the loop has long since exited, and i > 2.
Add a separate handler function:
var items=["#item-1","#item-2"];
var overlays=["#overlay-1","#overlay-2"];
function sethover(n) {
$(items[n]).hover(
function(){$(overlays[n]).css("visibility", "visible");},
function(){$(overlays[n]).css("visibility", "hidden");});
}
for (var i = 0; i < items.length; i++) {
sethover(i);
}

for (var i = 0; i < items.length; i++) {
$(items[i]).hover(function(){
$(this).find('.overlay').css("visibility", "visible");
}, function(){
$(this).find('.overlay').css("visibility", "hidden");
});
}

Related

How can i loop html element using jquery in javascript?

I want to repeat 'post' div and all of its contents eg 50times in left-col div using jquery and call it inside html?
HTML:
<div class="post"> Content </div>
JS:
var jQueryScript = document.createElement('script');
jQueryScript.setAttribute('src', 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js');
document.head.appendChild(jQueryScript);
$(document).ready(function(i) {
for (let i = 2; i < 100; i++) {
$(".post:eq(0)").clone().appendTo(".left-col");
}
});
You can do it like this:
$(document).ready(function(i) {
for (let i = 0; i < 50; i++) {
$(".post:eq(0)").clone().appendTo("#left-col");
}
});
There was a few problems with your code. First $("#post") should be $(".post"), since it's a class not an id.
Second your for loop was not correct. You were missing the {} and also it should be i < 50 not i < i.length(50)
Also important to note that I've added :eq(0) to $(".post"), since it would cause a big problem without.
Because first time the loop would run, you would have 1 element with the class post, second time you would have 3 elements, third time = 6 elements and so far.
$(document).ready(function(i) {
for (let i = 0; i < 50; i++) {
$(".post:eq(0)").clone().appendTo("#left-col");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post"> Content </div>
<div id="left-col"></div>

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');
});
}

How to show/hide a span using javascript

Can someone show a way to show/hide a span using javascript
document.getElementById("test").style.display= 'visible';
document.getElementById("test").style.display= 'block';
In the HTML Code
<span id='test' ..
How can I overcome this problem. Is there any thing that I should think about?
UPDATE
I have a class like this one, I want to force mouse hovering on it.
<div id="test" class="tooltip effect">
<div id="second" href="#"> .. </div>
On css:
tooltip{..}
effect{..}
effect:hover{..}
Another option I tried besides your code is
document.getElementById("test").onmouseover = test.hover;
Should I re-write the hover class to another name-class, or should I tweak your code?
Use display none/default:
document.getElementById("test").style.display= 'none';
document.getElementById("test").style.display= '';
Below are some types and some easy to remember rules about them:
Default: the elements default property (generally block or inline)
Block: Generally on a line by itself. Has the width and height attributes (among other size/positioning attributes)
inline: on the same line as other elements/text. Does not have height/width attributes
Inherit: Inherits the parent element's display type
visible isn't a value for the display, you want none
I would do something like this to handle it:
function HideAndSeek(selector) {
var elements = undefined;
var displays = [];
if (!!selector.id) {
elements = [document.getElementById(selector.id)];
} else if (!!selector.class) {
elements = document.getElementsByClass(selector.class);
}
for (var elementIndex = 0; elementIndex < elements.length; elementIndex++) {
displays[elementIndex] = elements[elementIndex].style.display;
}
this.hide = function() {
for (var elementIndex = 0; elementIndex < elements.length; elementIndex++) {
elements[elementIndex].style.display = "none";
}
};
this.show = function() {
for (var elementIndex = 0; elementIndex < elements.length; elementIndex++) {
elements[elementIndex].style.display = displays[elementIndex];
}
};
}
This function can be used this way:
var hideAndSeek = new HideAndSeek({id: "test"});
and you can hide the element(s) by:
hideAndSeek.hide();
you can show them by:
hideAndSeek.show();
<span class="text-danger" id="spanAddressLine1" runat="server" style="display: none;"> //Here is your message </span>
JQuery code
For show:
$('#<%= spanAddressLine1.ClientID%>').show();
For hide:
$('#<%= spanAddressLine1.ClientID%>').hide();
Here spanAddressLine1 is the id of span

Hover effects in for loops

Here is the HTML:
<div class=column1of4>
<a rel="Appendix" href="images/watermarks/watermark_pic1.jpg"
title="Bottle in the mirror">
<img src="images/250-width/pic1.jpg"
alt="" width="250px" height="250px"
id="Bottleinthemirrorpic">
</a>
<a rel="Appendix" href="images/watermarks/watermark_pic1.jpg"
title="Bottle in the mirror">
<div id="Bottleinthemirror" class="spanlink">
<p>Bottle in the mirror</p>
</div>
</a>
</div>
and here is the Javascript:
var texts = ['#Bottleinthemirror'];
var picture = ['#Bottleinthemirrorpic'];
for ( var i = 0; i < 1; ++i ) {
$.each(texts, function(i) {
$(this).hide();
$([this, picture[i]]).hover(function() {
$(this).show();
}, function() {
$(this).hide();
});
});
Basically, when I hover over #Bottleinthemirrorpic, I want #Bottleinthemirror to show up and I want #Bottleinthemirror to go away when I hover off of both of them.
I want the for loop because I am going to add more elements to texts and picture, I'm just wondering why the Javascript doesn't work? It doesn't seem to hide #Bottleinthemirror.
This code works but I want to be able to loop through the elements inside texts and picture which is why I am not using this code:
$('#Bottleinthemirror').hide();
$('#Bottleinthemirrorpic, #Bottleinthemirror').hover(function() {
// in
$('#Bottleinthemirror').show();
}, function() {
// out
$('#Bottleinthemirror').hide();
});
Nested loops are unnecessary, where the arrays are one-dimensional. You can try something like:
var texts = ['#Bottleinthemirror'],
pictures = ['#Bottleinthemirrorpic'],
i, j, curText, curPicture, generateHandlers;
generateHandlers = function (text, picture) {
$(text).hide();
$(text + "," + picture).hover(function () {
//in
$(text).show();
},function () {
//out
$(text).hide();
});
};
for (i = 0, j = texts.length; i < j; i++) {
curText = texts[i];
curPicture = pictures[i];
generateHandlers(curText, curPicture);
}
DEMO: http://jsfiddle.net/hQ8xt/
The immediate problem with binding events in a loop is that the event is triggered later, when the loop has finished. So by that time, the iterator (in this case, i) has reached the last value (in this case, j). You need to create a new scope to capture the values in the arrays, which is what I've done by calling the generatedHandlers function and passing the array values.
One thing I'd suggest is to combine the texts and pictures arrays into an object, like:
var textPics = {
'#Bottleinthemirror': '#Bottleinthemirrorpic'
};
And loop over that like:
var curText, curPicture;
for (curText in textPics) {
curPicture = textPics[curText];
generateHandlers(curText, curPicture);
}

How to hide all divs with JavaScript?

I am wondering how I can hide all divs on the page only using JavaScript, I cannot use jQuery. Is there a way to do this without using the arrays that comes with document.getElementByTag? Or if there is not, could you show me how to hide all?
Use getElementsByTagName() to get a list of all div elements, and then set their CSS display property to none:
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
divs[i].style.display = 'none';
}
<div>sads</div>
<div>sads</div>
<span>not a div</span>
You will need to use document.getElementsByTagName, and then use a for loop to process all of the elements:
var divs = document.getElementsByTagName('div');
for(var i = 0; i < divs.length; i++) {
divs[i].style.display = "none";
}
Just to put out a totally different solution here.
You could set a CSS class to your body, like this
body.hideDivs DIV {
display: none;
}
document.body.className = "hideDivs";
But this would hide everything inside those divs also, which might not be what you are going for here.

Categories