jquery stack overflow with simple slider - javascript

Unsatisfied with existing sliders (mostly because they're bloated code and require external script calls), I decided to try to write a simple, site-specific inline slider script. However, I get a stack overflow error.
<div id="featured">
<div class="tween">
<div class="cropimg">
</div>
<div class="container">
text
</div>
</div>
<div class="tween">
<div class="cropimg">
</div>
<div class="container">
text
</div>
</div>
<div class="tween">
<div class="cropimg">
</div>
<div class="container">
text
</div>
</div>
</div>
<script>
var _rys = jQuery.noConflict();
_rys("document").ready(function(){
var timeOut = 5000;
setTimeout(nextSlide(1),timeOut);
});
function nextSlide(next) {
var i = 1;
var numberOfChildren = _rys("#featured").children().length;
_rys(".tween:nth-child("+next+")").fadeTo(500,1);
while (i<=numberOfChildren) {
// loop through the children and make those that are opaque invisible
if (i != next) {
if (_rys(".tween:nth-child("+i+")").css('opacity') != 0) {
_rys(".tween:nth-child("+i+")").css('opacity',0);
}
}
i++;
}
if (next>=numberOfChildren) {
setTimeout(nextSlide(1), 5000);
} else {
setTimeout(nextSlide(next+1), 5000);
}
}
</script>

Related

Next(question) Button does not work when replay is done

This is a small quiz app which I am making to learn JS. It works fine and gives the proper result, but when clicked replay, it displays the quizBox but the 'Next' button does not work. There is no console error and I am unable to understand where to look for the error in the code.
This is the jsFiddle link of the working app
https://jsfiddle.net/lifet/t20h6gw8/10/
js has both the script and the questions file
This is the Html for the quiz and result box
<!--Start Quiz Box-->
<div class="row quiz_box">
<div class="col-md-6 col-sm-12">
<div class="card">
//other part of code
<!--Quix Box Footer-->
<footer>
<button class="next_btn">Next</button>
</footer>
</div>
</div>
</div>
</div>
<!--End Quiz Box-->
<!--Start Result Box-->
<div class="row result_box">
<div class="card col-md-6 col-sm-12">
//other part of code
<div class="buttons">
<button class="restart">Replay Quiz</button>
</div>
</div>
</div>
<!--End Result Box-->
</div>
This is the css for hiding and showing the result and quiz box respectively
.removeResultBox.result_box{
display: none;
}
.removeResultBox.quiz_box{
display: flex;
}
This is the js for replay function and next on click.
//---------------- restart Quiz-------------------//
const replayQuiz = resultBox.querySelector(".restart");
function showQuizBox(){}
replayQuiz.onclick=() =>{
quizBox.classList.add("removeResultBox");// this displays the quiz box
resultBox.classList.add("removeResultBox");// this hides the result box
queCounter = 0;
queNumber = 1;
startTime = 15;
widthValue = 0;
userScore =0;
showQuestions(queCounter);
questionCounter(queNumber);
clearInterval(timeCounter);
clearInterval(counterLine);
startTimer(startTime);
startTimeLine(widthValue);
nextBtn.style.display="none";
}
This is the next button onclick event
//go on to the next question
nextBtn.onclick=()=>{
console.log("next");
if (queCounter < questions.length - 1) {
queCounter++;
queNumber++;
showQuestions(queCounter);
questionCounter(queNumber);
clearInterval(timeCounter);
startTimer(startTime);
clearInterval(counterLine);
startTimeLine(widthValue)
nextBtn.style.display="none";
}
else {
showResultBox();
}
}
I am stuck badly and would really appreciate any help. Thank you!!
you have to change the line
const replayQuiz = document.querySelector(".restart");
check the website
In replayQuiz.onclick instead of adding removeResultBox try and remove showResultBox:
replayQuiz.onclick = () => {
resultBox.classList.remove('showResultBox')
quizBox.classList.remove('showResultBox')
...
}

How to get children of a div

User can, by pressing a button, select a particular topic of interest. When that happens, various divs will either become visible or invisible depending on whether that div has a link referring to that topic.
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
var topicAreas = area.getElementsByClassName("topicArea");
for (i = 0; i < topicAreas.length; i++) {
var children = topicAreas[i].children;
var topics = [];
for (j = 0; j < children.length; j++) {
topics.push(children[j].getAttribute("asp-route-name"));
document.getElementById("firstTest").innerHTML = children[j].toString();
}
var b = topics.includes(topic);
if (b == true) {
var parentId = document.getElementById(topicAreas[i]).parentNode.id;
document.getElementById(parent).style.display = 'block';
} else {
document.getElementById(parent).style.display = 'none';
}
}
}
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
The trouble, as far as I can tell, begin early in the JS part. I can see that when a do var children=topicAreas[i].children, I get nothing.
I hope this is what you're trying to do. Based on what button you click, respective div is displayed.
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
var topicAreas = area.getElementsByClassName("topicArea");
for (i = 0; i < topicAreas.length; i++) {
var children = topicAreas[i].children;
for (j = 0; j < children.length; j++) {
var parentId = topicAreas[i].parentNode.id;
if(children[j].getAttribute("asp-route-name") === topic){
document.getElementById(parentId).style.display = 'block';
}else{
document.getElementById(parentId).style.display = 'none';
}
}
}
}
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
Children isn't the issue. When you run your code you get the error "Uncaught TypeError: Cannot set property 'innerHTML' of null". Looking at your code where you are using .innerHTML, we see that you are trying to reference an element that you don't have in this code:
document.getElementById("firstTest")
Now, after adding that, you still have some items that you should change.
asp-action and asp-route-name are invalid HTML. Are you using a
framework that requires this syntax?
Don't use .getElementsByClassName().
Use .querySelectorAll() and Array.forEach() on the result for
easier looping.
Don't use .innerHTML when you aren't working with HTML strings as there are security and performance implications to doing so.
Avoid inline styles when you can. Using them causes duplication of code and code is harder to scale. Instead, use CSS classes and the .classList API.
It's not super clear exactly what is supposed to happen when clicking your buttons, but see the updated code below:
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
// Don't use .getElementsByClassName() as it provides a live node list
// and causes quite a performance hit, especially when used in loops.
// Use .querySelectorAll() and then use .forEach() on the collection that
// it returns to iterate over them.
area.querySelectorAll(".topicArea").forEach(function(area){
var topics = [];
// No need for children, here. Again, use .querySelectorAll()
area.querySelectorAll("*").forEach(function(child) {
topics.push(child.getAttribute("asp-route-name"));
document.getElementById("firstTest").textContent = child.getAttribute("asp-route-name");
});
if (topics.indexOf(topic) > -1) {
// Don't use inline styles if you can avoid it.
// Instead use pre-made classes.
area.classList.add("hidden");
}
else {
area.classList.remove("hidden");
}
});
}
/* Use CSS classes when possible instead of inline styles */
.hidden { display:none; }
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
<div id="firstTest"></div>

Trying to use javaScript to make the second image shows instead of the first

I'm trying to show the next image by just adding the style: display(none) but it is not working at all
<script>
function displayBanner() {
var count = 1;
if (count == 1) {
document.getElementById("banner_img3").style.display = "none";
}
}
displayBanner();
</script>
<header>
<div class="banner">
<div id="banner">
<div class="banner_img" id="banner_img1"></div>
<div class="banner_img" id="banner_img2"></div>
<div class="banner_img" id="banner_img3"></div>
</div>
</div>
</header>
Your element does not exist when you execute the script before the element. Move the script to after the elements or move displayBanner into a load event
I assume you want to rotate the images
var count = 0, max;
function displayBanner() {
document.getElementById("banner_img"+count).style.display = "none";
count++
if (count === max ) count = 0
document.getElementById("banner_img"+count).style.display = "block";
}
window.addEventListener("load", function() {
max = document.querySelectorAll(".banner_img").length;
document.getElementById("banner_img0").style.display = "block";
setInterval(displayBanner, 3000);
})
.banner_img { display:none; text-align:center }
<header>
<div class="banner">
<div id="banner">
<div class="banner_img" id="banner_img0"><img src="http://lorempixel.com/output/animals-q-c-640-480-1.jpg" /><br/>Image 1</div>
<div class="banner_img" id="banner_img1"><img src="http://lorempixel.com/output/animals-q-c-640-480-2.jpg" /><br/>Image 2</div>
<div class="banner_img" id="banner_img2"><img src="http://lorempixel.com/output/animals-q-c-640-480-3.jpg" /><br/>Image 3</div>
</div>
</div>
</header>
your div didn't have any source add a source using <img src=""></img> for the div try below code for that
<header>
<div class="banner">
<div id="banner">
<div class="banner_img" id="banner_img1"><img src="http://templatesforcv.com/wp-content/uploads/06.jpg" ></div>
<div class="banner_img" id="banner_img2"><img src="http://templatesforcv.com/wp-content/uploads/06.jpg"></div>
<div class="banner_img" id="banner_img3"><img src="http://templatesforcv.com/wp-content/uploads/06.jpg"></div>
</div>
</div>
</header>
window.onload=displayBanner();
function displayBanner() {
var count = 1;
if (count == 1) {
document.getElementById("banner_img3").style.display = "none";
}
}
working demo:https://jsfiddle.net/athulmathew/yh2esp1c/21/

Change text in multiple divs with same class onclick [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a list of football matches and would like to replace all scores with "?-?" when pressing a button and toggle back to show the score when pressing again.
div {
display: table;
}
div div {
display: table-row;
}
div div div {
display: table-cell;
}
.score {
color: blue;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Hide scores!</button>
<br> <br>
<div class="table">
<div class="match">
<div class="team1">Manchester United</div>
<div class="score">1-1</div>
<div class="team2">Liverpool</div>
</div>
<div class="match">
<div class="team1">Juventus</div>
<div class="score">2-0</div>
<div class="team2">Inter Milan</div>
</div>
<div class="match">
<div class="team1">Real Madrid</div>
<div class="score">1-4</div>
<div class="team2">Barcelona</div>
</div>
<div class="match">
<div class="team1">Dortmund</div>
<div class="score">3-0</div>
<div class="team2">Bayern Munich</div>
</div>
<div class="match">
<div class="team1">PSG</div>
<div class="score">0-1</div>
<div class="team2">Marseille</div>
</div>
</div>
I have experimented with getElementById and innerHTML, but due to the large number of matches I would prefer to use getElementsByClassName instead. I've seen people recommending querySelectorAll() for this, but I can't get the scripts to work.
An alternative would be to run a script replacing all numbers with a question mark inside divs with the same class.
Please help me out by using this fiddle
Here's a solution that uses querySelector only to select the button and the .table element to toggle a class.
The rest is all CSS, so no looping is needed.
Note that this exchanges your .score text content for a data-score attribute.
document.querySelector("button")
.addEventListener("click", function() {
document.querySelector("div.table").classList.toggle("hide-score");
});
.table .score:after {
content: attr(data-score);
}
.table.hide-score .score:after {
content: "?-?";
}
<button>Hide scores!</button>
<br>
<br>
<div class="table">
<div class="match">
<div class="team1">Manchester United</div>
<div class="score" data-score="1-1"></div>
<div class="team2">Liverpool</div>
</div>
<div class="match">
<div class="team1">Juventus</div>
<div class="score" data-score="2-0"></div>
<div class="team2">Inter Milan</div>
</div>
<div class="match">
<div class="team1">Real Madrid</div>
<div class="score" data-score="1-4"></div>
<div class="team2">Barcelona</div>
</div>
<div class="match">
<div class="team1">Dortmund</div>
<div class="score" data-score="3-0"></div>
<div class="team2">Bayern Munich</div>
</div>
<div class="match">
<div class="team1">PSG</div>
<div class="score" data-score="0-1"></div>
<div class="team2">Marseille</div>
</div>
</div>
To support older browsers, you could instead keep the score as text content, but put it in a span with another <span>?-?</span> next to it, and then configure the CSS to hide the :first-child and show the rest as needed.
If you don't want to change your html code
$.each($('.score'), function(key, score) {
var score_text = $(score).text();
$(score).data('score', score_text)
})
$('button').click(function() {
if ($(this).data('hiding-score')) {
$(this).data('hiding-score', false);
$.each($('.score'), function () {
$(this).text($(this).data('score'));
});
} else {
$(this).data('hiding-score', true);
$('.score').text('?-?');
}
})
div { display:table; }
div div { display:table-row; }
div div div { display:table-cell; }
.score { color:blue; padding:10px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Hide scores!</button>
<br>
<br>
<div class="table">
<div class="match">
<div class="team1">Manchester United</div>
<div class="score">1-1</div>
<div class="team2">Liverpool</div>
</div>
<div class="match">
<div class="team1">Juventus</div>
<div class="score">2-0</div>
<div class="team2">Inter Milan</div>
</div>
<div class="match">
<div class="team1">Real Madrid</div>
<div class="score">1-4</div>
<div class="team2">Barcelona</div>
</div>
<div class="match">
<div class="team1">Dortmund</div>
<div class="score">3-0</div>
<div class="team2">Bayern Munich</div>
</div>
<div class="match">
<div class="team1">PSG</div>
<div class="score">0-1</div>
<div class="team2">Marseille</div>
</div>
</div>
Here is a fiddle with plain old Javascript.
But I have to admit, #SkinnyPete's way is way better and easier to understand ! You shouls use it if you're only to hide the score. This is the best way to go.
// Mandatory JS code
const score = document.getElementsByClassName('score')
const button = document.getElementById("hide")
const initialState = []
for(let i = 0; i < score.length; i++){
initialState.push({initial : score[i].innerHTML})
}
button.addEventListener('click', (e) => {
const dynamicScore = document.getElementsByClassName('score')
for(let i = 0; i < dynamicScore.length; i++){
if(dynamicScore[i].innerText === initialState[i].initial){
dynamicScore[i].innerHTML = "?-?"
}else{
dynamicScore[i].innerHTML = initialState[i].initial
}
}
})
i added an id "hide" to your button this works fine
The solution I would recommend is that you make use of data attributes on the divs to store the scores. i.e. <div class="score" data-for="1" data-against="1">1-1</div>. Then it's easier to toggle the values. Since you're using jQuery,
// Set the values to ?-?
$('.match .score').html('?-?');
// set the actual scores
$('.match .score').each(function(){
$(this).html($(this).data('for') + '-' + $(this).data('against'));
});
My solution:
I would use the temporary storage. U can set the values for each element with the data()-Method
//STORE DATA IN TEMP STORAGE
$( ".score" ).each(function( index ) {
$(this).data("score-temp", $(this).text());
});
On Click-Event I would add a class "hide-score" to distinguish between both states. And if hide-score is already set, than you reset the values from the temporary storage
$("button").click(function() {
if ($(".table").hasClass( "hide-score" )) {
$(".table").removeClass("hide-score");
//set VALUE FROM TEMP STORAGE
$( ".score" ).each(function( index ) {
var score_temp = $(this).data("score-temp" );
$(this).text(score_temp);
});
}
else {
$( ".score" ).text("?-?");
$(".table").addClass("hide-score");
}
});

unwanted class with display: none making content invisible

I am getting unwanted class (.page) as the page loads with css property display: none, which makes the content invisible. I haven't inserted any class(.page). I have tried to undo the css property none to block via a JS but its not working. I can't figure out the problem. Its strange.
Here is the html that I actually coded:
<div class="deck-background"></div>
<div id="page">
<div id="main">
<div id="content" class="column" role="main">
<a id="main-content"></a>
<the main html content sits here>
</div>
</div>
</div>
This I am getting as the page loads. Please note two new divs with class (.page).
<div class="deck-background"></div>
<div id="page">
<div id="main">
<div id="content" class="column" role="main">
<div class="page" style="display: block;">
<a id="main-content"></a>
</div>
<div class="page" style="display: none;">
<the main html content sits here>
</div>
</div>
</div>
</div>
Here is the JS:
<script type="text/javascript">
window.onload = function() {
function showHide(id) {
var el = document.querySelectorAll('.page')
if( el && el.style.display == 'block')
el.style.display = 'none';
else
el.style.display = 'block';
}
}
</script>
Here is the JS
window.onload = function() {
var nodes = document.querySelectorAll('.page');
[].forEach.call(el, function(el){
el.style.display = "block";
});
}

Categories

Resources