I'm creating a website just for myself, and want to make divs with text appear in order (some interval between appearance will be great) after the page will load. I don't need any special animation.
I tried to find something on Stack Overflow or anywhere else, but I couldn't. It should be some kind of "copy" of messenger.
Here is what I got:
<div class="messages-area">
<div class="message bubbledLeft">
<p>Hey!</p>
</div>
<div class="message bubbledLeft last-bubbled-left">
<p>Did you hear about it?</p>
</div>
<div class="message bubbledRight last-bubbled-right">
<p>Huh? About what?</p>
</div>
<div class="message bubbledLeft">
<p>About this new website!</p>
</div>
</div>
https://jsfiddle.net/2p860Lxt
You could first hide them with CSS (for instance with display: none in the .message class), and then use the promise returned by .delay().promise() to show them with delay, and chain those promises with reduce:
$(".message").get().reduce(function (acc, div) {
return acc.then(function () {
return $(div).show().delay(400).promise();
});
}, $.when()); // start with a resolved promise
.message { display: none };
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<div class="messages-area">
<div class="message bubbledLeft">
<p>Hey!</p>
</div>
<div class="message bubbledLeft last-bubbled-left">
<p>Did you hear about it?</p>
</div>
<div class="message bubbledRight last-bubbled-right">
<p>Huh? About what?</p>
</div>
<div class="message bubbledLeft">
<p>About this new website!</p>
</div>
</div>
You don't need jQuery for this. Here's how you could do it with plain JavaScript:
HTML:
<div id="message-area"></div>
JavaScript:
function addMessage() {
var container = document.getElementById("message-area");
var messageElem = document.createElement("div");
messageElem.setAttribute("class", "message-area__message");
messageElem.appendChild(document.createTextNode("my message"));
container.appendChild(messageElem);
}
window.addEventListener('load', function() {
console.log('loaded')
for (var i=0; i<5; i++) {
window.setTimeout(addMessage, 500*i);
}
});
This will add 5 message elements into the message area, 500 milliseconds apart.
Related
Basically, I'm asking for a way to optimize this code. I'd like to cut it down to a few lines because it does the same thing for every click bind.
$("#arch-of-triumph-button").click(function(){
$("#arch-of-triumph-info").addClass("active-info")
});
$("#romanian-athenaeum-button").click(function(){
$("#romanian-athenaeum-info").addClass("active-info")
});
$("#palace-of-parliament-button").click(function(){
$("#palace-of-parliament-info").addClass("active-info")
});
Is there a way to maybe store "arch-of-triumph", "romanian-athenaeum", "palace-of-parliament" into an array and pull them out into a click bind? I'm thinking some concatenation maybe?
$("+landmarkName+-button").click(function(){
$("+landmarkName+-info").addClass("active-info")
});
Is something like this even possible?
Thanks in advance for all your answers.
EDIT: Here's the full HTML.
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button"></div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button"></div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Assuming you're not able to modify your HTML markup (in which case with use of CSS classes would be cleaner), a solution to your question would be as shown below:
// Assign same click handler to all buttons
$("#arch-of-triumph-button, #romanian-athenaeum-button, #palace-of-parliament-button")
.click(function() {
// Extract id of clicked button
const id = $(this).attr("id");
// Obtain corresponding info selector from clicked button id by replacing
// last occurrence of "button" pattern with info.
const infoSelector = "#" + id.replace(/button$/gi, "info");
// Add active-info class to selected info element
$(infoSelector).addClass("active-info");
});
Because each .landmark-button looks to be in the same order as its related .landmark-info, you can put both collections into an array, and then when one is clicked, just find the element with the same index in the other array:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
This does not rely on IDs at all - feel free to completely remove those from your HTML to declutter, because they don't serve any purpose now that they aren't being used as selectors.
Live snippet:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
.active-info {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button">click</div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button">click</div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Older answer, without knowing the HTML: You can extract the ID of the clicked button, slice off the button part of it, and then select it concatenated with -info:
$(".landmark-button").click(function() {
const infoSel = this.id.slice(0, this.id.length - 6) + 'info';
$(infoSel).addClass('active-info');
});
A much more elegant solution would probably be possible given the HTML, though.
When i hover over one element, all of them are highlighted
here is my html and jquery code
$('.hover-text').hide();
$('.movie-content').hover(
function () {
$('.movies_post_text').hide();
$('.hover-text').show();
},
function () {
$('.movies_post_text').show();
$('.hover-text').hide();
}
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="movie-content movie-big" style="background-image: url('Images/incidentbyabank-900x498.jpg');">
<a href="http://www.cricbuzz.com">
<div class="movies_post_text">
<h3>INCIDENT BY A BANK</h3>
<p>Sweden/12 MIN</p>
<p>Award Winning, Drama, Thriller</p>
<p>DIR.Ruben Ostlund</p>
</div>
<div class="hover-text">
<div class="row movie-info">
<div class="col-md-4">
<div class="reactions pull-left">
<div class="view">429<i class="fa fa-eye"></i></div>
<div class="like">252<i class="fa fa-thumbs-up"></i></div>
</div>
</div>
<div class="col-md-8">
<h3 class="grid-title">INCIDENT BY A BANK</h3>
<div class="movie-desc">
<p>Shot using a single camera, 90 people meticulously recreate a failed bank robbery that took place in Stockholm in June 2006. A superb single shot.The short went on to win the Golden Bear at </p>
</div>
</div>
</div>
</div>
</a>
</div>
Please suggest me any solutions to this with jquery or any html classes to use.Help me to get rid of it i know that if i use this it get resolved but how to use that this to get it working
The problem is that in your event callbacks you're not restricting your selectors to the operate only within the hovered parent.
$('.hover-text').hide();
$('.movie-content').hover(
function () {
$('.movies_post_text').hide(); //<-- all matching elements, not just the
// one inside the hovered div
$('.hover-text').show(); //<-- same here
},
function () {
$('.movies_post_text').show(); //<-- " "
$('.hover-text').hide(); //<-- " "
}
);
Should be
$('.hover-text').hide();
$('.movie-content').hover(
function () {
$(this).find('.movies_post_text').hide();
$(this).find('.hover-text').show();
},
function () {
$(this).find('.movies_post_text').show();
$(this).find('.hover-text').hide();
}
);
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");
}
});
I want to get the text on click with a certain class but nothing works. I have a div with 2 p tags and I want to get both separate. Also, I want to append them. .append() appends but just keeps adding all targeted events. empty().append() gives me random results (on first click it works, on second I get half of the text etc). Ive tried most of what I could find on stack overflow but nothing helped. Any help would be great!
Ive tried:
$(event.target).text(); //that gives me the text, but not both p elements separate
$(this).hasClass('.video-title'); //only returns to me true/false
var title= document.getElementsByClassName("video-title")[0].innerHTML; //doesn't give me the current element.
$('p.video-title').innerHTML; //doesnt help either
HTML
<div class="video-container">
<iframe id="vid_frame" src="https://www.youtube.com/embed/xxx?rel=0&showinfo=0&autohide=1" width="900" height="450"></iframe>
<div id="video-info"></div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" onClick="attachSrc('yyy', event)">
<img src="assets/images/thumbnail/yourHeart_official.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 1</p>
<p class="video-author">author 1</p>
</div>
</div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" onClick="attachSrc('xxx', event)">
<img src="assets/images/thumbnail/yourHeart_karaoke.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 2</p>
<p class="video-author">author 2</p>
</div>
</div>
</div>
<script>
function attachSrc(id, event) {
var text = $(event.target).text();
$('#video-info').append(text);
}
</script>
As you are using jQuery, I would recommend you to use unobtrusive event handler and use .on() to attach event handlers.
Here in example I have attached event with wrapper element and DOM traversal method to traverse and target desired element.
And to persists arbitrary data use data-* prefixed custom attribute which can be fetched using .data(key)
<div class="video-wrapper" data-id="yyy">
Script
$('.video-col').on('click', '.video-wrapper', function() {
var elem = $('#video-info').empty();
var title = $(this).find('.video-title').text();
elem.append(title);
console.log(title);
var author= $(this).find('.video-author').text();
elem.append(author);
console.log(author);
console.log($(this).data('id'));// To fetch custom data associated with element
});
$(function() {
$('.video-col').on('click', '.video-wrapper', function() {
console.clear();
var elem = $('#video-info').empty();
var title = $(this).find('.video-title').text();
elem.append(title);
console.log(title);
var author = $(this).find('.video-author').text();
elem.append(author);
console.log(author);
console.log($(this).data('id')); // To fetch custom data associated with element
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="video-container">
<div id="video-info"></div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" data-id="yyy">
<img src="assets/images/thumbnail/yourHeart_official.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 1</p>
<p class="video-author">author 1</p>
</div>
</div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" data-id="xxx">
<img src="assets/images/thumbnail/yourHeart_karaoke.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 2</p>
<p class="video-author">author 2</p>
</div>
</div>
</div>
Figured I would ask here because I can't seem to find an easy solution or a solution on here that fits my needs. The problem I'm having with my site at the moment is when dealing with slide animations and with timing of those animations.
So when a user clicks one of my navigation buttons there is a panel that slides out the content based on the button pressed. if you click another button it will slide that one previous div back up and slide down the new content panel.
The main problem I'm getting is either I get animation timing issues because the other one starts sliding as the other one is for some reason.
All my content panels are siblings to one another...so here's the jQuery I'm using....any suggestions would be greatly appreciated!
$('a.navBtn').click(function(){
var divName = this.name;
$.when(function(){
$("#"+divName).siblings().filter(":visible").slideUp("slow");
}).then(function(){
$("#"+divName).slideDown("slow");
})
});
<div id="services">
<div class="noise_overlay">
<div id="contact"><img src="i/contact.png" /></div>
<div id="linkedin"><img src="i/linkedin.png" /></div>
<div id="facebook"><img src="i/facebook.png" /></div>
<div id="twitter"><img src="i/twitter.png" /></div>
<div id="flickr"><img src="i/flickr.png" /></div>
</div>
</div>
<div id="serviceContent">
<div id="contactContent" class="contentPane mpHidden">
<div class="noise_overlay_300">
<div id="contactData">
<span>contact</span>
</div>
</div>
<div class="contentFooter"></div>
</div>
<div id="linkedinContent" class="contentPane mpHidden">
<div class="noise_overlay_300">
<div id="linkedinData" class="mpCenter">
</div>
</div>
<div class="contentFooter"><span></span></div>
</div>
<div id="facebookContent" class="contentPane mpHidden">
<div class="noise_overlay_300">
<div id="facebookData" class="mpCenter">
<span>facebook</span>
</div>
</div>
<div class="contentFooter"><span></span></div>
</div>
<div id="twitterContent" class="contentPane mpHidden">
<div class="noise_overlay_300">
<div id="twitterData" class="mpCenter">
<span>twitter</span>
</div>
</div>
<div class="contentFooter"><span></span></div>
</div>
<div id="flickrContent" class="contentPane mpHidden">
<div class="noise_overlay_300">
<div id="flickrData" class="mpCenter">
<span>flickr</span>
</div>
</div>
<div class="contentFooter"><span></span></div>
</div>
</div>
You need to chain your animation events so the slideDown doesn't happen until the slideUp is done:
http://api.jquery.com/slideUp/
$("#"+divName).siblings().filter(":visible").slideUp("slow", function() {
$("#"+divName).slideDown("slow");
});
Should be something like that.
I have made a simple jQuery snippet for you. The javascript:
$(function() {
$('a.navBtn').click(function(e) {
var pane = $(this).attr('name'),
switchPanes = function(name) {
if($('.contentPane:visible').attr('id') === name){
return;
}
if($('.contentPane:visible').length > 0){
$('.contentPane:visible').slideUp('fast', function() {
$('#' + name).slideDown('medium');
});
} else {
$('#' + name).slideDown('medium');
}
};
switchPanes(pane);
e.preventDefault();
});
});
Here's a working(?) version. I use the callback of the slideUP to call the slideDown.
http://jsfiddle.net/yazYF/
EDIT: Just like the Justin said, I just have some code to test with. :)
EDIT 2: Now with an initial pane visible
http://jsfiddle.net/yazYF/1/
EDIT 3: Initially nothing...
http://jsfiddle.net/yazYF/2/