I'm using a plugin that allow to add popup to images,i want that when i click on a popup i can navigate between all popups with previous and next buttons.
Here is my element when its showen :
<div class="imp-tooltip.imp-tooltip-visible" style="border-radius: 5px; padding: 20px; background: rgba(0, 0, 0, 0.9)"></div>
and i tried this :
<nav>
<button id="down" ></button>
<button id="up" ></button>
</nav>
var $currentElement = $(".imp-tooltip imp-tooltip-visible").first();
$("#down").click(function () {
var $nextElement = $currentElement.next('.imp-tooltip');
if($nextElement.length) {
$currentElement = $nextElement;
$('html, body').stop(true).animate({
scrollTop: $nextElement.offset().top
}, 1000);
}
return false;
});
$("#up").click(function () {
var $prevElement = $currentElement.prev('.imp-tooltip');
if($prevElement.length) {
$currentElement = $prevElement;
$('html, body').stop(true).animate({
scrollTop: $prevElement.offset().top
}, 1000);
}
return false;
});
There's a couple of little errors in your code.
HTML: class="imp-tooltip.imp-tooltip-visible"Should be: class="imp-tooltip imp-tooltip-visible"
JS: $(".imp-tooltip imp-tooltip-visible").first()Should be: $(".imp-tooltip-visible").first()
What is the purpose of the imp-tooltip-visible class? Is it there to indicate what is currently the active element? If so, then you forgot to remove this class from $currentElement before assigning a new element to it. And after performing this operation this class should be added to the new $currentElement. This would also make the .first() part in the selector redundant since there should only be one element with this class.
If on the other hand this class indicates which imp-tooltip divs are actually visibly available, then the next() and prev() functions should be targeting imp-tooltip-visible instead of imp-tooltip.
Related
$(document).ready(function() {
$(".button1").click(function() {
$("html, body").animate({
scrollTop : $("#screen1").offset().top
}, 800);
});
})
$(document).ready(function() {
$(".button2").click(function() {
$("html, body").animate({
scrollTop : $("#screen2").offset().top
}, 800);
});
})
...and so on
I wrote above code in javascript. If button is clicked, it scrolls to #screen position. However, I have several ".button"s and "#screen"s that basically has the same function. I don't want to repeat the same code so I've tried for in statement, but couldn't get it right. In what way can I avoid repeating codes in this situation?
Now, I cant see your HTML code, but my suggestion would be to add the event listener to a parent element to all the buttons and then add info about the button on the button itself. Here I'm using the attribute data-screen to hold info about the "screen".
UPDATE
I refined the jquery a bit. Using on() instead of click() so that I could remove the original if statement. When the event listener is on the parent element more buttons can be added dynamically and they will work as expected.
$(document).ready(function() {
$("#buttons").on("click", "button", function(e) {
var screenid = $(e.target).attr('data-screen');
$("html, body").animate({
scrollTop: $(`#screen${screenid}`).offset().top;
}, 800);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="buttons">
<button data-screen="1">Button 1</button>
<button data-screen="2">Button 2</button>
<button data-screen="3">Button 3</button>
</div>
<div>
<div id="screen1"></div>
<div id="screen2"></div>
<div id="screen3"></div>
</div>
Assuming all the buttons & screens follow the naming convention .button${number} and #screen${number}, you can do this:
const numberOfSections = 5;
$(document).ready(function() {
for (let i = 1; i <= numberOfSections ; i++) {
$(`.button${i}`).click(function() {
$("html, body").animate({
scrollTop : $(`#screen${i}`).offset().top
}, 800);
});
}
});
How is it possible to make the text I am not clickable for some reason... (check the code below) clickable?
var container = document.querySelector('.container');
var clickMe = document.querySelector('.clickMe');
clickMe.addEventListener('click', function() {
var container = document.querySelector('.container');
$([document.documentElement, document.body]).animate({
scrollTop: $(".container").offset().top
}, 1000);
});
container.addEventListener('wheel', function() {
var scrollY = window.scrollY;
if (scrollY == 0) {
$([document.documentElement, document.body]).animate({
scrollTop: $(".nextContainer").offset().top
}, 800);
}
});
.container {
background: green;
height: 100vh;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<p class="clickMe">'wheel'</p>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<div class="nextContainer">
<p class="clickMe">I am not clickable for some reason...</p>
</div>
As you see, the Wheel-listener works perfectly, while the click-listener does not. How do I solve this problem, if possible?
Thanks in advance.
The problem appear because you get only first clickable element here :
var clickMe = document.querySelector('.clickMe');
So, you attach the click event just at first element "wheel" text.
The solution to fix this problem is to get all ".clickMe" elements with querySelectorAll and attach click event to each element.
var clickMe = document.querySelectorAll('.clickMe');
clickMe[0].addEventListener('click', function() {
var container = document.querySelector('.container');
$([document.documentElement, document.body]).animate({
scrollTop: $(container).offset().top
}, 1000);
});
clickMe[1].addEventListener('click', function() {
var container = document.querySelector('.container');
$([document.documentElement, document.body]).animate({
scrollTop: $(container).offset().top
}, 1000);
});
Are you sure it's not clickable. In function which handle paragraph click add console.log("CLICKED"); and see in console if anything appears when you click. And in css add style for clickMe cursor:pointer; so when you hover it looks better.
Finally figured out the problem.
After the animation,
$([document.documentElement, document.body]).animate({
scrollTop: $(".nextContainer").offset().top
}, 800);
I needed to add JQuery:s stop() function,
$('html, body').stop();
Credits: Stop ScrollTop function when user scrolls jquery
Instead of document.querySelector('.clickMe') you can use the jQuery Selector $('.clickMe').
Than it works fine.
var container = document.querySelector('.container');
var clickMe = document.querySelector('.clickMe');
console.log(clickMe);
$('.clickMe').on('click', function() {
console.log('clicked');
var container = document.querySelector('.container');
$([document.documentElement, document.body]).animate({
scrollTop: $(".container").offset().top
}, 1000);
});
container.addEventListener('wheel', function() {
var scrollY = window.scrollY;
if (scrollY == 0) {
$([document.documentElement, document.body]).animate({
scrollTop: $(".nextContainer").offset().top
}, 800);
}
});
.container {
background: green;
height: 100vh;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<p class="clickMe">'wheel'</p>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<div class="nextContainer">
<p class="clickMe">I am not clickable for some reason...</p>
</div>
I have a jQuery code obtained from w3schools.com which ON CLICK (clicking an ) changes URL's #id and also allows smooth scrolling to a particular DIV section. But its not working on scroll. I want the same with an scrolling effect. When I scroll down or up to a particular section the URL's #id should change.
Current jQuery Code:
$(document).ready(function(){
$("#navlist a").on('click', function(event) {
if(this.hash !== ""){
var hash = this.hash;
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function(){
window.location.hash = hash;
});
}
});
});
I searched on stackoverflow and I got something like this:
$(document).bind('scroll',function(e){
$('div').each(function(){
if ($(this).offset().top < window.pageYOffset + 10 && $(this).offset().top + $(this).height() > window.pageYOffset + 10){
window.location.hash = $(this).attr('id');
}
});
});
This seems to work but when I place both the code either one of them is stopping the other one from executing. I thought of combining both the codes into one to achieve both onclick and scroll effect but I am not being able to do so (weak hands on jquery yet).
Example URL with ID: http://localhost/sites/fh/index.php#first
Please help me devs.
Instead of setting the location hash, you should change the history state. That way you will avoid forced page scrolling by browser. Check it below:
navlist = [];
$("#navlist a").each(function(i) {
var thisLink = $(this);
var thisId = thisLink.attr('href');
var thisTarget = $(thisId);
navlist.push({
'anchor': thisLink,
'id': thisId,
'target': thisTarget
});
thisLink.on('click', function(e) {
e.preventDefault();
$('html, body').animate({
scrollTop: thisTarget.offset().top
}, 800);
});
});
$(window).on('scroll resize', function(e) {
$.each(navlist, function(e, elem) {
var placement = elem.target[0].getBoundingClientRect();
if( placement.top<window.innerHeight && placement.bottom>0 ) {
history.pushState({}, '', elem.id);
console.log('Hash: ' + elem.id);
return false; /* Exit $.each loop */
};
});
});
nav a {
display: block;
}
section {
height: 600px;
border-top: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="navlist">
Go to Section 1
Go to Section 2
Go to Section 3
</nav>
<section id="s1">Section 1 Content</section>
<section id="s2">Section 2 Content</section>
<section id="s3">Section 3 Content</section>
Also on JSFiddle.
Please note, if you are using Foundation framework, than you already have Magellan.
For Bootstrap it is called ScrollSpy.
I have this button in my HTML that basically collapses/expands the #leftmenu and it's working okay: <a id="menutoggle" data-toggle="collapse" data-target="#leftmenu">Placeholder</a>
I want to accomplish this:
If #leftmenu is visible when you load the page then add
top:-10px property to #contentfix.
If #leftmenu is collapsed by clicking the collapse button then remove top:-10px property from #contentfix.
If #leftmenu is expanded by clicking the collapse button then add top:-10px property to #contentfix.
I basically want the top:-10px property in my #contentfix whenever #leftmenu is visible and top:0px whenever it is hidden. Regardless of whether page had it visible/hidden by default or you changed it by clicking the collapse button.
Here's my current attempt:
if ($("#leftmenu").is(":visible")) {
$('#contentfix').css('top','-10px');
var visible = 1;
}
$('#menutoggle').click(function(e) {
$('html, body').animate({ scrollTop: 0 }, 'fast');
if (visible == 0){
$('#contentfix').css('top','-10px');
visible = 1;
} else {
$('#contentfix').css('top','0px');
visible = 0;
}
});
Make sure to use $(document).ready(). Moreover you can cache jQuery objects and do not need to set a visible variable and write the same functionality twice.
$(document).ready(function(){
var contentFix = $('#contentfix');
var leftMenu = $("#leftmenu");
var menuToggle = $('#menutoggle');
var htmlBody = $('html, body');
var toggle = function(){
htmlBody.animate({ scrollTop: 0 }, 'fast');
if (leftMenu.is(":visible")) {
contentFix.css('top','-10px');
} else {
contentFix.css('top','0px');
}
}
menuToggle.on('click', function() {
toggle();
});
});
I have this JS code
<script>
$('.tile').on('click', function () {
$(".tile").addClass("flipOutX");
setTimeout(function(){
$('.metro .tile-area-darkCrimson').css('backgroundColor','#4c7fb5');
$(".tile-group.main").css({ marginLeft:"-40px", width: "1080px"}).load("musability-musictherapy-company-overview.html");
}, 2000);
});
</script>
The .tile class applies to all the buttons which are all called tile .
Is there any way to introduce a unique identifier without having to repeat this script for every button individually.
This is an example of the tile ref in the html
<a class="tile double bg-tile1color live animated flipInX" data-click="transform">
use $(this), it applies only on the element you clicked
$('.tile').on('click', function() {
$(this).addClass("flipOutX");
setTimeout(function() {
$('.metro .tile-area-darkCrimson').css('backgroundColor', '#4c7fb5');
$(".tile-group.main").css({
marginLeft: "-40px",
width: "1080px"
}).load("musability-musictherapy-company-overview.html");
}, 2000);
});