In my site when URL is something like this: www.example.com/question/#comment23
i want to scroll to this and i use this code:
if (window.location.hash) {
var elem = $(window.location.hash);
var elemId = $(elem).attr('id')
var top = $('#' + elemId).offset().top - 60;
var moreCmntElm = $('#' + elemId).closest('.comment-wrp').siblings('.create-comment-wrp').children('.moreCommnets');
$('html, body').animate({
scrollTop: top
}, 1600, 'easeInOutQuart')
if (moreCmntElm.css('display') == "none") {
moreCmntElmFunc(moreCmntElm.children('button')[0])
}
}
But its possible the comment is hidden display:none (like stackoverflow when a question has a lot of comment), in this case i want the show more comment button event to be trigger.
This function show other comments:
function moreCmntElmFunc($this) {
$this.closest('.other-user-comments-wrp').children().show('blind', 'fast');
$this.css('display', 'none');
$this.parent().css('display', 'none');
}
But code work properly and other comments are displayed.
My problem is i get an error and else other JS operation doesn't work.
$this.closest(...).children is not a function
Since children() is a jQuery function and moreCmntElm.children('button')[0] returns underlying DOM element and they can't execute the jQuery function. Thus you are getting the error
Use .eq()
moreCmntElmFunc(moreCmntElm.children('button').eq(0)); //.first() can also be used
instead of
moreCmntElmFunc(moreCmntElm.children('button')[0]);
Related
I'm writing a quiz web ap with an opening heading and then 10 questions that follow it. The div of the opening and the div of each question are all siblings, so I traverse the page by passing current.nextSibling and current.previousSibling to whatever functions I'm using.
Right now I'm trying to create a smooth scroll with jQuery through its 'animate' and 'scrollTop' methods, but it's not working. Does anyone have any thoughts on this? Code attached here, link to fiddle here: https://jsfiddle.net/fjydnc9m/1/
var main = function () {
var root = $('html, body');
var current = document.getElementById("opening");
$('.upButton').click(function () {
$('html, body').animate({ scrollTop:$(current.previousSibling).offset().top}, 2000);
current = current.previousSibling;
});
$('.downButton').click(function() {
$('html, body').animate({ scrollTop: $(current.nextSibling).offset().top}, 2000);
current = current.nextSibling;
});
}
$(document).ready(main);
You've been trying to use jQuery .offset() on a regular HTML DOM element.
See this updated version of the fiddle:
https://jsfiddle.net/fjydnc9m/12/
What I did is to get the prev and next sibling via jQuery and use .offset() on that.
Note that you'll also have to account for the cases where current is the first or last wrapper, or some strange scrolling will take place. You can do this by checking if the length of prevSibling or nextSibling is > 0 before scrolling.
If you log the current variable, you find out that there is a #text sibling that is assigned to the current variable.
Check out this fiddle:
https://jsfiddle.net/fjydnc9m/13/
You can see that I assigned the current variable twice PRIOR to using it in the scrollTop function:
var main = function() {
var root = $('html, body');
var current = document.getElementById("opening");
$('.upButton').click(function() {
current = current.previousSibling;
current = current.previousSibling;
$('html, body').animate({
scrollTop: $(current).offset().top
}, 2000);
console.log(current);
});
$('.downButton').click(function() {
current = current.nextSibling;
current = current.nextSibling;
$('html, body').animate({
scrollTop: $(current).offset().top
}, 2000);
console.log(current);
});
}
$(document).ready(main);
Note that I'm logging the current variable. Remove one of the current assignments and see what the log shows (you will see what's going on).
The scenario is this:
Link from an RSS feed into my website http://website.com/#anchorelement
I'd like to jump/scroll to #anchorelement
However, #anchorelement is loaded using jQuery.load() after http://website.com/ is ready. As a result, using the link http://website.com/#anchorelement does not jump to #anchorelement because the element has yet to be loaded when performing the jump.
Does anyone have any suggestions on how to make this work? Is it possible to intercept the anchor jump with javascript and make it wait until the jQuery.load() call is complete?
Thanks!
$(function(){
// so this is inside your document ready function.
// you need to add a callback
$( somecontainer ).load('somecontent', function(){
// after the content has been loaded
// check if a hash is present in the location
if( window.location.hash != '' ){
// find an element with matching id
var anchor = $( location.hash ).get(0);
// if element was found scroll it into view
if( anchor ){ anchor.scrollIntoView() }
}
});
});
If you have multiple content to load, load it one per one using callback function and if you want to scroll on one of them, call function scroll on the last callback.
$(function ()
{
//Get the hash and load your content
var hash = location.hash.replace('#', '');
loadLocationContent(hash);
});
function loadLocationContent(hash)
{
$('container1').load("someContent1", function(){
$('container2').load("someContent2", function(){
$('container3').load("someContent3", function(){
$('container4').load("someContent4", scrollToHashAfterContentLoad(hash));
});
});
});
}
function scrollToHashAfterContentLoad(hash, contentId)
{
if (hash != '')
{
$('html, body').animate({ scrollTop: $('#' + hash).offset().top }, 2000);
}
}
I am new to web development and I am in a little trouble. I am using the following jQuery function in order to scroll the page for specific divs with internal links.
$('a[href^="#"]').on('click', function(event) {
var target = $( $(this).attr('href') );
if( target.length ) {
event.preventDefault();
$('html, body').animate({
scrollTop: target.offset().top-30
}, 1000);
}
});
The problem is that the function works also on other elements with internal links that should not have the scroll effect (accordion elements). The only way I can prevent this from happening is to write the same function for all the links that I want to apply the function to ("#link1", "#link2", "#link3", "#link4", ... , "#linkn").
I tried to use an array with the links and to use each value of the array in the function but I don't know how to write the loop.
Can you please help me?
$('a[href^="#"]')
This selector is saying "get all a tags that start with href=#". So the best idea would be to change this selector, to instead go by class names.
You could for example do this:
link
And js:
$('.autoscrollLink').on('click', function(event) {
var target = $( $(this).attr('href') );
if( target.length ) {
event.preventDefault();
$('html, body').animate({
scrollTop: target.offset().top-30
}, 1000);
}
});
I'm currently using 'smooth scroll' on my wordpress page, and I'm attempting to have the page smoothly scroll to the requested section when coming from an external link (using anchors ( #portfolio)from there I want the page to start at the top and THEN scroll to the portfolio section.
What's happening is it briefly displays the 'portfolio section' (anchor jump) and THEN resets to the top and scrolls down.
Code
$(function() {
$('.menu li a').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$root.animate({
scrollTop: target.offset().top - 75
}, 800, 'swing');
return false;
}
}
});
});
page load
$(window).on("load", function() {
if (location.hash) { // do the test straight away
window.scrollTo(0, 0); // execute it straight away
setTimeout(function() {
window.scrollTo(0, 0); // run it a bit later also for browser compatibility
}, 1);
}
var urlHash = window.location.href.split("#")[1];
if (urlHash && $('#' + urlHash).length)
$('html,body').animate({
scrollTop: $('#' + urlHash).offset().top - 75
}, 800, 'swing');
});
How do I prevent the 'jumping' that seems to happen on page load?
HTML - nav links (using dummy links)
<a href="link.com/#portfolio>portfolio</a>
HTML - divs
<div id="portfolio></div>
You can circumvent the browser behavior by changing the anchor so that it carries some additional text that will be unique to the page visit. In the example below, I've added the first six lines to your function to set the AnchorSeed variable, and then I've used that variable where you assign the urlHash variable:
$(window).on("load", function() {
var AnchorSeed = new Date() * 1;
$( ".AnchorUpdate" ).each(
function() {
$( this ).attr( "id", this.id + AnchorSeed );
}
);
if (location.hash) { // do the test straight away
window.scrollTo(0, 0); // execute it straight away
setTimeout(function() {
window.scrollTo(0, 0); // run it a bit later also for browser compatibility
}, 1);
}
var urlHash = window.location.href.split("#")[1] + AnchorSeed;
if (urlHash && $('#' + urlHash).length)
$('html,body').animate({
scrollTop: $('#' + urlHash).offset().top - 75
}, 800, 'swing');
});
And you'll need to add the AnchorUpdate class to any page element that you might jump to, so that the jQuery routine can find it and update its id with the AnchorSeed value. In this case, we know that "portfolio" is such a link, so it would be modified as:
<div class="AnchorUpdate" id="portfolio></div>
The effect of this is that the id will change from "portfolio" to something like "portfolio1382124849780" (depending, of course, on the time stamp when the page was loaded).
Because the id "portfolio" won't exist when the page finishes loading (even though it is part of the source HTML), the browswer shouldn't bounce to it.
I used JavaScript entirely because I didn't know if you had access to server variables. If you do, I think they might be a preferable solution, as the code will be more readable. You might use a page counter variable, or simply a server-side timestamp, if possible.
Edit:
In the comments you mentioned that this was working for external links, but that it broke internal links. I don't have time to set up a test right now, but I think it would work to add a jQuery routine to update those internal links similar to what is being done above. For example, your internal link is:
Jump to Internal Link
You might give it a different class indicating that it needs updating:
<a class="InternalLinkUpdate" href="#InternalLink">Jump to Internal Link</a>
And then trigger a similar modification of that class using jQuery:
$( ".InternalLinkUpdate" ).each(
function() {
$( this ).attr( "href", $( this ).attr( "href" ) + AnchorSeed );
}
);
(Since I'm not able to copy from working code at the moment, I might have made a punctuation error or such in the above -- but it shouldn't take too much tinkering to get it to work properly.
I am working on a "one page" website with a fixed navigation and about 5 different pages inside the one document.
UPDATED WORKING LINK
http://www.coco-works.com/Archive/ LIVE VERSION
I'm having trouble with the active class addition. When you click Keep in Touch or Home, the class is not applied. As you can see from the live version, it's not function properly.
The page works something like this;
And here is the JavaScript;
$(document).ready(function() {
$('body').click(function(event) {
if (event.target.nodeName.toLowerCase() == 'a') {
var op = $(event.target);
var id = op.attr('href');
if (id.indexOf('#') == 0) {
$.scrollTo(id, 1000, {
offset: {
top: 75
},
axis: 'y',
onAfter: function() {
window.location.hash = id.split('#')[1];
}
});
}
return false;
}
});
$.fn.waypoint.defaults.offset = 75;
$('.section h1.page_name').waypoint(function() {
var id = this.id;
var op = $('#navigation a[href = "#' + id + '"]');
if (op.length) {
$("#navigation a").removeClass("active");
op.addClass('active');
}
});
});
I'm not a strong programmer. I've tried to edit it as best as I can and I'm just stuck. Any insight to fixing this would highly be appreciated.
Still looking for an answer, below couldn't fix the problem.
I'm not sure what the waypoints plugin was doing, but I've refactored your code and it is working for me. Note that I took out the call to .waypoints, and changed your $('body').click() handler to be a more specific handler on the navigation link elements. This handler will scroll to each element and then will perform the removal and addition of the class correctly when the scrolling is done:
$(document).ready(function()
{
function highlightNav(navElement){
$("#navigation a").removeClass('active');
navElement.addClass('active');
}
$('#navigation a').click(function(event){
var nav = $(this);
var id = nav.attr('href');
$.scrollTo(id, 1000, {
offset: { top: -75 },
axis: 'y',
onAfter: function(){
highlightNav(nav);
}
});
return false;
});
$(window).scroll(function(){
if($(this).scrollTop() == 0){
highlightNav($("#navigation a[href*='home']"));
}
});
$.fn.waypoint.defaults.offset = 75;
$('.section h1.page_name').waypoint(function() {
var id = this.id;
var op = $('#navigation a[href = "#' + id + '"]');
if (op.length) {
highlightNav(op);
}
});
// Fancybox
$("a.zoom").fancybox({
'overlayShow' : false,
'transitionIn' : 'elastic',
'transitionOut' : 'elastic'
});
$("a.outside_shade").fancybox({
'titlePosition' : 'outside',
'overlayColor' : '#000',
'overlayOpacity' : 0.9
});
$("a.inside_white").fancybox({
'titlePosition' : 'inside'
});
$("a.inside_shade").fancybox({
'titlePosition' : 'over'
});
// validation
$("form").validate();
// nivo slider
$('#slider').nivoSlider();
});
In the html I added a default active class to the first link:
<div id="navigation">
<ul>
<li>Home</li>
<li>Portfolio</li>
<li>Who Are We?</li>
<li>Our Services</li>
<li>Features</li>
<li>Keep in Touch</li>
</ul>
</div>
Also I noticed on the page you have your css defined before the reset.css is called in. That's usually bad practice you might want to make sure reset.css is always the very first css file pulled in. It doesn't appear to have affected the page much but sometimes you'll get weird results doing that.
I made a jsfiddle of the results here: http://jsfiddle.net/RNsFw/2/
the waypoints plugin isn't needed anymore I think. I didn't change the fancybox or validation stuff because i'm not sure what those are doing and it wasn't really part of your issue.
I tested it in firefox and Chrome. Let me know if you have questions :)
http://jsfiddle.net/vCgy8/9/
This removes the dependency on scrollTo, and the waypoints plugin.
$('body').click(function(event)
{
if(event.target.nodeName.toLowerCase() == 'a')
{
var op = $(event.target);
var id = op.attr('href');
if(id.indexOf('#') == 0)
{
destination = $(id).offset().top;
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, 1000, function() {
var hash = id.split('#')[1];
window.location.hash = hash;
});
}
return false;
}
});
$(window).scroll(function (event){
makeActive();
});
function makeActive(){
var y = $(this).scrollTop();
if(y!==0){
$('.page_name').each(function(){
var curPos = parseInt($(this).offset().top - y);
if(curPos <= 0){
var op = $('#navigation a[href = "#'+$(this).attr('id')+'"]');
$("#navigation a").removeClass("active");
op.addClass('active');
}
});
}else{
$("#navigation a").removeClass("active");
$("#navigation a:first").addClass('active');
}
}
makeActive();
This may be completely unrelated, but I had a similar problem yesterday - where, in the callback of an event handler, jQuery operations weren't being performed in that scope but if you threw the code into something like:
setTimeout(function() {
$(selector).addClass('foo');
}, 0);
it would work - similar to how $.animate() functions (ish) if you call $(selector).stop().animate() without the queue param being false, eg:
$(selector).stop();
$(selector).animate({ foo }, { no queue:false here });
// ^ fail
$(selector).stop();
setTimeout(function() {
$(selector).animate({ foo }, { no queue:false here either });
}, 0);
// ^ success
The problem, completely unrelated to the above example though similar in behavior/functional hack, turned out to be the method of binding - in my case I had been using $.bind() - but then I refactored this to use $.delegate() ($.live() would work also) and it functioned as expected.
Again, not sure if this related, but figured I'd pass that along just in case. Unsure if it's a bug or just me not properly understanding some of the subtler parts of jQuery.
The problem is not in your js code, but in your css/page layout.
Or maybe the problem is that you are using the waypoint plugin and you might not want to for this particular page. (As you will see you also have trouble hitting the "Home" waypoint again once you have left it, because of the offset you use.)
The thing is, the waypoint plugin won't trigger until the target element you are scrolling to is in the very top of the browser window, with respect to the offset that is. "Keep in touch" will never get to the top unless your browser window is small enough that the "keep in touch" section takes up the entire browser window (minus the offset).
You can see it visualized here: