Javascript hiding objects in loop - javascript

Please help me. I want to hide ext by clicking on link, but something is wrong
But I could write only this, and don't undertand why it's not working! Maybe there is another way to do it? It's every time fills the same function. to li1 li2func, therefore thereis li1
Link to jsfiddler
html:`
<div>
<div class="left">
<ul>
<li><a id="11" href="#">one</a></li>
<li><a id="12" href="#">two</a></li>
<li><a id="13" href="#">three</a></li>
</ul>
</div>
<div class="right">
<p id="1">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque, qui.
</p>
<p id="2">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus reiciendis veritatis voluptatibus optio explicabo? Dignissimos ex amet mollitia doloribus a.
</p>
<p id="3">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Impedit porro quisquam harum nemo, vitae itaque.</p>
</div>
</div>`
JS code:
var el = document.getElementsByTagName("p");
var cs = document.getElementsByTagName("a");
if(el) {
for (i = 0; i < el.length; i++) {
td = cs[i];
(function (_td) {
td.addEventListener('click', function(){
console.log(_td);
console.log(i);
document.getElementsByTagName("div")[i].className += document.getElementsByTagName("div")[i].className ? ' invis' : 'invis';
});
})(td);

You have a few problems with your javascript. You should have noticed this error in your javascript console: "Uncaught TypeError: Cannot read property 'className' of undefined", which might have led you to discover that document.getElementsByTagName("div") is not the selector you should be using. You did the work to produce an array of p tags (inexplicably named el), but then didn't make any reference to that within the closure you built.
Here's one way to fix that problem: give your closure a second argument, and pass the p tag of the corresponding number (i) to the a tag to which you're binding the click handler. Then modify the className string of that element.
var el = document.getElementsByTagName("p");
var cs = document.getElementsByTagName("a");
if(el) {
for (i = 0; i < el.length; i++) {
td = cs[i];
ptag = el[i];
(function (_td,_el) {
td.addEventListener('click', function(){
console.log(_td);
console.log(i);
_el.className += _el.className ? ' invis' : 'invis';
});
})(td,ptag);
}
}
One other thing: you'll notice that console.log(i) always produces 3 because that i is not bound to the scope of the click handler, but rather the outer scope of the for loop, so when the user clicks on one of the a tags, the loop has already completed and i will always equal 3.

While you tagged jquery this is how can you do with jquery by using the index() of href's closest li
$('ul > li > a').on('click' , function(){
var ThisId = $(this).closest('li').index();
$('div.right > p:eq('+ThisId+')').slideToggle(100);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="left">
<ul>
<li><a id="11" href="#">one</a></li>
<li><a id="12" href="#">two</a></li>
<li><a id="13" href="#">three</a></li>
</ul>
</div>
<div class="right">
<p id="1">
1 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque, qui.
</p>
<p id="2">
2 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus reiciendis veritatis voluptatibus optio explicabo? Dignissimos ex amet mollitia doloribus a.
</p>
<p id="3">3 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Impedit porro quisquam harum nemo, vitae itaque.</p>
</div>
</div>

document.getElementsByTagName will never return null, so if(el) in your code is unnecessary. An empty array will always evaluate to true. If you want i to not equal 3, then you have to add it to the closure at the moment it is 0, 1, and 2. I called it _index here:
var paragraphs = document.getElementsByTagName("p");
var links = document.getElementsByTagName("a");
for (i = 0; i < paragraphs.length; i++) {
link = links[i];
paragraph = paragraphs[i];
(function (_link,_paragraph, _index) {
_link.addEventListener('click', function(){
console.log(_link);
console.log(_index);
_paragraph.classList.toggle('invis');
});
})(link,paragraph, i);
}
Here is a cleaner version
function init(link, paragraph, index) {
link.addEventListener('click', function(){
paragraph.classList.toggle('invis');
});
}
var paragraphs = document.getElementsByTagName("p");
var links = document.getElementsByTagName("a");
for (i = 0; i < paragraphs.length; i++) {
init(links[i], paragraphs[i], i);
}

Related

CPU overheating when uploading images with JavaScript

The problem is simply that I wrote the code below to upload random text and images with the same name but the last number in names changed, but this leads to an increase in the processor temperature,
here is the code :
let ctn=document.getElementById("y_main");
function mainCtn(str,i){
var post= ` <section class="y_post">
<article class="y_post_article">
<h3>${str}</h">
<p> Lorem ipsum dolor sit amet consectetur adipisicing elit.
Enim error dolores nulla vero animi a ex perspiciatis repellendus neque
doloremque! Dolor culpa odio ea, excepturi eaque in similique tempore earum!</p>
<img width="200px" src="image/postimage/img_post${i}.pn" alt="post img">
</article>
<section class="y_post_btn">
<button class="post_lbtn"><img src="icon/check.svg" alt="chat" srcset=""></button>
<button class="post_cobtn"><img src="icon/chat-square-text.svg" alt="chat" srcset=""></button>
<button class="post_shbtn"><img src="icon/share.svg" alt="chat" srcset=""></button>
</section>
<div class="y_comment_block">
<button class="close_btn_comment">close</button>
<p class="text_comment"></p>
<div class="comment_tool">
<textarea name="" class="input_comment" cols="30" rows="1" placeholder="insert comment"></textarea>
<button class="btn_comment">add</button>
</div>
</div>
</section>`
return post;
}
let b=1;
setInterval(function () { if(b<12){
ctn.innerHTML+=mainCtn(`#${b}`,b);b++;
}
else{
clearInterval(myInterval);
}
}, 2000);
Just like #KompjoeFriek mentioned you need the setInterval ID, not an id you hardcode.
let b =1
const myInterval = setInterval(function () {
if(b<12){
ctn.innerHTML+=mainCtn(`#${b}`,b);b++;
} else{
clearInterval(myInterval);
}
}, 2000);
This should work.

JavaScript: How to generate nested ordered list

How to generate nested ordered lists from the following content? I have searched the forum and worked for a few hours now to generate ordered lists based on the different classes from the source content. The content may have up to 6 nesting
level.
What I need is to generate ordered lists based on the different classes. As shown in the sample content to get something like below outlined example content.
.firstclass => 1.
.secondclass => 1.
.thirdclass => 1.
.fourthclass => 1.
The code:
var cheerio = require('cheerio');
var $ = cheerio.load('<h1 class="header">First Header</h1><p class="firstclass">First Lorem ipsum dolor sit.</p><p class="firstclass">First Qui consequatur labore at.</p><p class="secondclass">Second Lorem ipsum dolor sit amet.</p> <p class="thirdclass">Third Lorem ipsum dolor sit amet.</p><p class="thirdclass">Third Molestias optio quasi ipsam unde!</p><p class="secondclass">Second Lorem ipsum dolor sit amet, consectetur.</p><p class="fourthclass">Fourth Lorem ipsum dolor sit.</p><p class="firstclass">First Lorem ipsum dolor sit amet.</p>', {
normalizeWhitespace: true,
xmlMode: true,
decodeEntities: false,
});
var myContent = $('p').each(function() {
var para = $(this).text();
return para;
});
var olClass = ['.firstclass', '.secondclass', '.thirdclass', '.fourthclass'];
function arrToOl(arr) {
var ol = $('<ol />'),
li = $('<li />');
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
li.append(arrToOl(arr[i]));
} else {
li = $('<li />');
li.append($(arr[i]));
ol.append(li);
}
}
return $.html(ol);
}
console.dir(arrToOl(olClass));
The above code produces the following:
'<ol><li><p class="firstclass">First Lorem ipsum dolor sit.</p><p class="firstclass">First Qui consequatur labore at.</p><p class="firstclass">First Lorem ipsum dolor sit amet.</p></li><li><p class="secondclass">Second Lorem ipsum dolor sit amet.</p><p class="secondclass">Second Lorem ipsum dolor sit amet, consectetur.</p></li><li><p class="thirdclass">Third Lorem ipsum dolor sit amet.</p><p class="thirdclass">Third Molestias optio quasi ipsam unde!</p></li><li><p class="fourthclass">Fourth Lorem ipsum dolor sit.</p></li></ol>'
The desired result should be:
<ol>
<li>
<p class="firstclass">First Lorem ipsum dolor sit.</p>
</li>
<li>
<p class="firstclass">First Qui consequatur labore at.</p>
</li>
<li>
<p class="firstclass">First Lorem ipsum dolor sit amet.</p>
<ol>
<li>
<p class="secondclass">Second Lorem ipsum dolor sit amet.</p>
</li>
<li>
<p class="secondclass">Second Lorem ipsum dolor sit amet, consectetur.</p>
<ol>
<li>
<p class="thirdclass">Third Lorem ipsum dolor sit amet.</p>
</li>
<li>
<p class="thirdclass">Third Molestias optio quasi ipsam unde!</p>
<ol>
<li>
<p class="fourthclass">Fourth Lorem ipsum dolor sit.</p>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
Your help is really appreciated.
Here's what I got.
let array = ["a", "b", "c", "d"];
var nested;
function create_nested()
{
var old_ol;
for (let i = 0; i < array.length; i++)
{
let new_ol = document.createElement("ol");
let new_li = document.createElement("li");
new_li.innerHTML = array[i];
new_ol.appendChild(new_li);
if (i !== 0)
{
let nest_li = document.createElement("li");
let new_p = document.createElement("p");
new_p.innerHTML = "new stuff";
nest_li.appendChild(new_p);
nest_li.appendChild(old_ol);
new_ol.appendChild(nest_li);
}
old_ol = new_ol;
nested = new_ol;
}
}
create_nested();
document.getElementById('main').appendChild( nested);
<div id='main'>
</div>
This is just an example and not exactly the data that you have (you can figure that out).
What's happening is that I'm creating new elements using document.createElement, after which I am inserting them into their corresponding ol/li using appendChild.
The most important part is the if (i !== 0) (Change this to suit whether you want to start from the beginning or end of your array). This is the part where I am creating the nests.
I am creating a new li, which has the <p> and the old_ol which is the nesting li. So what this function is doing, is creating the innermost ol, and expanding it upward.
There might be a clear/better way of doing this, but this is as far as I know in vanilla JS. I hope everything is clear enough.

Accordion AJAX JSON content

I have the following html structure
<div class="accordion-container">
<ul class="accordion">
<li class="accordion-header">
<a class="is-active link">Accordion header<i class="accordion-header-icon"></i></a>
<div class="accordion-content js-accordion-content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum, quos!</p>
</div>
</li>
<li class="accordion-header">
<a class="link">Accordion header<i class="accordion-header-icon"></i></a>
<div class="accordion-content js-accordion-content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla sed ducimus iusto, atque veniam, laborum ratione quibusdam sapiente. Sint.</p>
</div>
</li>
<li class="accordion-header">
<a class="link">Accordion header<i class="accordion-header-icon"></i></a>
<div class="accordion-content js-accordion-content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla sed ducimus iusto, atque veniam, laborum ratione quibusdam sapiente. Sint.</p>
</div>
</li>
<li class="accordion-header">
<a class="link">Accordion header<i class="accordion-header-icon"></i></a>
<div class="accordion-content js-accordion-content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla sed ducimus iusto, atque veniam, laborum ratione quibusdam sapiente. Sint.</p>
</div>
</li>
</ul>
</div>
and this css
.accordion-content {
display: none; }
I'm trying to populate the accordion-content with content from a json file only when click on each accordion header (.link)
I've tried this but it doesn't work as intended. When I click on a header it populates all the other accordion-content.
$(document).ready(function () {
$('.accordion').each(function (index) {
$(this).children('li').first().children('a').addClass('is-active').next().addClass('is-open').show();
});
$('.accordion').on('click', 'li > a', function (event) {
if (!$(this).hasClass('is-active')) {
event.preventDefault();
var accordionTabs = $(this).closest('.accordion');
accordionTabs.find('.is-open').removeClass('is-open').slideUp('fast');
$(this).next().toggleClass('is-open').slideToggle('fast');
accordionTabs.find('.is-active').removeClass('is-active');
$(this).addClass('is-active').closest('.accordion-content', function () {
$.getJSON('public/js/result.json', function (jd) {
$('.js-accordion-content').html('<p>Name: ' + jd.name + '</p>');
$('.js-accordion-content').append('<p>Age : ' + jd.age+ '</p>');
$('.js-accordion-content').append('<p>Sex: ' + jd.sex+ '</p>');
});
});
} else {
event.preventDefault();
}
});
});
The json looks like this:
{
"name": "Zara Ali",
"age" : "67",
"sex": "female"
}
jQuery's closest method does not accept an anonymous function as the 2nd argument, and therefore this never fires in your code.
$(this).addClass('is-active').closest('.accordion-content', function () {
I don't see you doing anything with the .accordion-content selector anyway, so just omit it.
$(this).addClass('is-active');
$.getJSON(....
You will also need to cache a reference to your element that fired the click event in order to reference in within the result of your ajax callback:
var self = $(this);
We need to natively wrap it as a jQuery object because the 2nd argument we pass in as context needs to apply .parent() in order to actually get the .js-accordion-content element.
$('.js-accordion-content', self.parent()).html('<p>Name: ' + jd.name + '</p>');
$('.js-accordion-content', self.parent()).append('<p>Age : ' + jd.age + '</p>');
$('.js-accordion-content', self.parent()).append('<p>Sex: ' + jd.sex + '</p>');
jsFiddle
The query ".js-accordion-content" is ambiguous to all similar elements with the same class name. Isolate it to the current "accordion"
replace:
$(this).addClass('is-active').closest('.accordion-content', function () {
$.getJSON('public/js/result.json', function (jd) {
$('.js-accordion-content').html('<p>Name: ' + jd.name + '</p>');
$('.js-accordion-content').append('<p>Age : ' + jd.age+ '</p>');
$('.js-accordion-content').append('<p>Sex: ' + jd.sex+ '</p>');
});
with
var self = this;
$(this).addClass('is-active').closest('.accordion-content', function () {
$.getJSON('public/js/result.json', function (jd) {
$('.js-accordion-content', self).html('<p>Name: ' + jd.name + '</p>');
$('.js-accordion-content', self).append('<p>Age : ' + jd.age+ '</p>');
$('.js-accordion-content', self).append('<p>Sex: ' + jd.sex+ '</p>');
});
Notice the use of self referencing the accordion.

Delete an element from the code using jquery

I'm trying Jquery and now I have a problem.
I want to remove an element from my webpage. So, when I press the delete button - the big element must disappear. Using the JQ I have written something like this
$(document).ready(function(){
$(".delete").click(function(){
$(this).parents(".block").animate({ opacity: 'hide' }, "slow");
})
});
It have worked fine until I didn't add subdiv, or answer. And how the application must works now? I press the delete button and it must remove current block.
<div class = "block">
<div class = "postbuttons">
<img src = "img/delete-icon.png" class = "delete"></a>
<img src = "img/edit-icon.png" class = "edit"></a>
</div>
<div class = "postinfo">
<span class = "author">Da Monkey wrote:</span> <span class = "date">on <span>13.13.13</span></span>
</div>
<div class = "post">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, voluptate, unde, impedit iste sint assumenda consequatur ipsum nesciunt</p>
<a class = "answerlink" href = "#">Answer</a>
</div>
<div class = "answer">
<div class = "postbuttons">
<img src = "img/delete-icon.png" class = "delete"></a>
<img src = "img/edit-icon.png" class = "edit"></a>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fuga, numquam, culpa, omnis explicabo ut asperiores ipsam porro alias quisquam nisi iste non a maiores! Nulla odio unde dolorum officia vero. </p>
<div class = "answerinfo">
- Macaque on <span>13.13.13</span>
</div>
</div>
If you didn't understand me here the result
Respect to the funcionality:
$(document).ready(function(){
$(".delete").click(function(){
$(this).closest(".block").animate({ opacity: 'hide' }, "slow");
});
});
you should use closest instead of parents because it stop once it has found the first math and parents travels to the root of the dom. Also if you dont need the block anymore you can remove it with the jquery method remove(), after tue animation ended with a callback function.
Also you are missing some semicolons, and tags
$(document).ready(function(){
$(".delete").click(function(){
$(this).parents(".block").animate({ opacity: 'hide' }, "slow");
}) // here needs a semicolon
});
Missing tags
<div class = "block">
<div class = "postbuttons">
<img src = "img/delete-icon.png" class = "delete"></a> <--! missing <a> -->
<img src = "img/edit-icon.png" class = "edit"></a> <--! missing <a> -->
</div>
<div class = "postinfo">
<span class = "author">Da Monkey wrote:</span> <span class = "date">on <span>13.13.13</span></span>
</div>
<div class = "post">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, voluptate, unde, impedit iste sint assumenda consequatur ipsum nesciunt</p>
<a class = "answerlink" href = "#">Answer</a>
</div>
<div class = "answer">
<div class = "postbuttons">
<img src = "img/delete-icon.png" class = "delete"></a> <--! missing <a> -->
<img src = "img/edit-icon.png" class = "edit"></a> <--! missing <a> -->
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fuga, numquam, culpa, omnis explicabo ut asperiores ipsam porro alias quisquam nisi iste non a maiores! Nulla odio unde dolorum officia vero. </p>
<div class = "answerinfo">
- Macaque on <span>13.13.13</span>
</div>
</div>
I hope I was Useful.
Try hiding the container of the container of the delete button, which will work regardless of its class:
$(document).ready(function(){
$(".delete").click(function(){
$(this).parents(".postbuttons").parent().animate({ opacity: 'hide' }, "slow");
})
});

jQuery plugin cycle2 caption is not animating up and down during slideshow

I cant get the animation of the caption / overlay to work. I want the caption to slide up and down from the bottom as the slides go in and out. I tried a bunch of things and I couldn't get it to work. My slides are made up of divs not images. Not sure if I put the HTML for the captions in the right place. I included the caption2 plugin.
Jsfiddle
<div class="cycle-slideshow slider"
data-cycle-slides = "> div"
data-cycle-fx="scrollHorz"
data-cycle-timeout="3000"
data-cycle-caption-plugin="caption2"
data-cycle-caption-fx-out="slideUp"
data-cycle-caption-fx-in="slideDown"
>
<div class="slide1 slide">
<div class= "innerWrapper" data-cycle-title="Spring">
<p class ="slide1text">This is a great div Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatum, unde, vel ratione nulla illum libero fuga placeat corporis molestias quisquam.</p> <img class ="slide1img" src="http://dummyimage.com/300x150/000/fff&text=slide1" alt=""/>
<br>
Click More
</div>
<div class="cycle-overlay">The Redwoods 1</div>
</div>
<div class="slide2 slide">
<div class = "innerWrapper" data-cycle-title="Spring" data-cycle-desc="Sonnenberg Gardens">
<img class ="slide2img" src="http://dummyimage.com/250x150/000/fff&text=slide2" alt=""/>
<p class ="slide2text">Text for slide 2 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, molestias incidunt ab voluptatibus id nemo error delectus sunt impedit illum.</p>
</div>
<div class="cycle-caption">Test</div>
<div class="cycle-overlay"></div>
</div>
</div>
Jsfiddle
Thank you for your help in advance.
Remove the "test" text from cycle-caption and put it into cycle-overlay so it is consistant with the other slides. then this javascript should get you started:
$( '.cycle-slideshow' ).on( 'cycle-after', function(event, optionHash, outgoingSlideEl, incomingSlideEl, forwardFlag) {
$(incomingSlideEl).find('.cycle-overlay').slideDown();
$(outgoingSlideEl).find('.cycle-overlay').slideUp();
});
you may have to play around with it a bit.
http://jsfiddle.net/w95ya/1/
Check this link to see what events you can listen for: http://jquery.malsup.com/cycle2/api/

Categories

Resources