I have a simple Bootstrap modal setup, and in the modal I have content with a nav and scrollspy set up. However, it isn't working. I see it gets activated, but the nav is never updated.
The full source is too long for here and you wouldn't be able to see the effect I am getting, so I have set up a jsfiddle
I am using the data-spy="scroll" method to enable it. What have I done wrong? Why isn't the nav being update with your position?
bootstrap scrollspy still has some bugs (i really love bootsrap at all).
i use a custom script for this it works way better and is more flexible:
<script type="text/javascript">
$(document).ready(function(){
var lastId, topMenu = $(".menu-sidebar"),
topMenuHeight = topMenu.outerHeight() + 150,
menuItems = topMenu.find("a"),
scrollItems = menuItems.map(function() {
var item = $($(this).attr("href"));
if (item.length) {
return item;
}
});
menuItems.click(function(e) {
var href = $(this).attr("href"),
topMenuHeight = topMenu.outerHeight() + 20,
offsetTop = href === "#" ? 0 : $(href).offset().top - topMenuHeight + 1;
$('html, body').stop().animate({
scrollTop: offsetTop
}, 300);
e.preventDefault();
});
$(window).scroll(function() {
var fromTop = $(this).scrollTop() + topMenuHeight;
var cur = scrollItems.map(function() {
if ($(this).offset().top < fromTop) return this;
});
cur = cur[cur.length - 1];
var id = cur && cur.length ? cur[0].id : "";
if (lastId !== id) {
lastId = id;
menuItems.parent().removeClass("active").end().filter("[href=#" + id + "]").parent().addClass("active");
}
});
});
</script>
source: http://jsfiddle.net/mekwall/up4nu/
Hey I think there are two issues here:
(1) putting scrollspy on something other than the body causes problem. Check out this:
In Twitter Bootstrap's ScrollSpy, where exactly can I put data-spy="scroll"?
basically if you add:
#area-to-watch {
height: 200px;
overflow: auto;
}
it will you allow you to scrollspy to "spy" on something other than the body.
http://jsfiddle.net/hajpoj/SZYKM/
This a modified version of your jsfiddle
(2) Putting scrollspy into a model causes more problems. If you put the above into a model, it kind of freaks out.
I'm not positive but I think you need to do something like
.scrollspy('refresh')
stated in the docs http://twitter.github.com/bootstrap/javascript.html#scrollspy
Please make sure that your bootstrap folder contains all the .js files required for ScrollSpy
In my case my bootstrap folder (bootstrap/js/) has the following files :
<script src="bootstrap/js/jquery.js"></script>
<script src="bootstrap/js/bootstrap-transition.js"></script>
<script src="bootstrap/js/bootstrap-alert.js"></script>
<script src="bootstrap/js/bootstrap-modal.js"></script>
<script src="bootstrap/js/bootstrap-dropdown.js"></script>
<script src="bootstrap/js/bootstrap-scrollspy.js"></script>
<script src="bootstrap/js/bootstrap-tab.js"></script>
<script src="bootstrap/js/bootstrap-tooltip.js"></script>
<script src="bootstrap/js/bootstrap-popover.js"></script>
<script src="bootstrap/js/bootstrap-button.js"></script>
<script src="bootstrap/js/bootstrap-collapse.js"></script>
<script src="bootstrap/js/bootstrap-carousel.js"></script>
<script src="bootstrap/js/bootstrap-typeahead.js"></script>
<script src="bootstrap/js/bootstrap-affix.js"></script>
<script src="bootstrap/js/holder/holder.js"></script>
<script src="bootstrap/js/google-code-prettify/prettify.js"></script>
<script src="bootstrap/js/application.js"></script>
You should call .scrollspy('refresh') after the modal has been shown like this:
$('#myModal').on('shown.bs.modal', function (e) {
$('.modal-body').scrollspy('refresh');
});
Related
Actually i am trying to achieve smooth scrolling in Jquery, and whatever code i have written seems to be working fine, but i also want to implement a feature where my Nav Class Changes to active when user scroll down/up based on the position. Below link to code will give you more idea on what i am talking about. problem i am facing is even though i click on the next nav sub element active class is set to previous element. i have user window.scroll of query infact this part is actually got it from net. i really dint understand the code that is why its hard fa me debug and fix it, so if anyone is able to fix it, it would be really good if you explain me what this code is actually doing and what is the problem with current implementation.
http://codepen.io/anon/pen/GqJmK
JS
$(document).ready(function(){
var lastId,
header = $("#header"),
topMenu = $("#nav"),
topMenuHeight = topMenu.outerHeight()+header.outerHeight()+25,
menuItems = topMenu.find("a"),
//menuItems = topMenu.find("a:not([href^='http://'],[href^='/'])"),
scrollItems = menuItems.map(function(){
var item = $($(this).attr("href"));
if (item.length) { return item; }
});
menuItems.on('click',function (e) {
e.preventDefault();
_this = this;
var target = _this.hash,
$target = $(target);
//menuItems.parent().removeClass("active");
//$(_this).parent().addClass("active");
$('html, body').stop().animate({
'scrollTop': ($target.offset().top) - topMenuHeight + 1
}, 900, 'swing', function () {
window.location.hash = target;
});
});
$(window).scroll(function(){
var fromTop = $(this).scrollTop()+topMenuHeight;
var cur = scrollItems.map(function(){
if (($(this).offset().top +20)< fromTop){
return this;
}
});
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
if (lastId !== id) {
lastId = id;
menuItems
.parent().removeClass("active")
.end().filter("[href=#"+id+"]").parent().addClass("active");
}
});
/*$( window ).resize(function() {
alert($( window ).width());
alert($( document ).width());
}); */
});
You might be best off using some sort of a plugin to achieve this effect. Something like http://lirancohen.github.io/stickUp/ or http://www.outyear.co.uk/smint/demo/ would do the trick
Just update your scroll check function & make your position check little more flexible i.e let it consider that you entered a section little before it enters it. Make this change on line 35 in your code -
if (($(this).offset().top - 50)< fromTop)
WORKING DEMO - http://codepen.io/nitishdhar/pen/LEAzI
You can also improve your UI by implementing this - http://css-tricks.com/hash-tag-links-padding/
Hoping for some help with this, as I'm not exactly a js expert.
I have a countdown set up, adapted from Keith Wood's countdown. It's not counting down in any browser, though it seems to be functioning perfectly in every other regard.
Here she is on jfiddle.
And here's the code:
html:
<div id="form">
<div id="topbox">
<div class="countdown"></div>
<div id="until">
until move-in
</div>
</div>
</div>
js:
$(document).ready(function() {
//preload rollover image
var image = $('<img />').attr('src', '../../images/countdown_button1.png');
// jqueryUI calls for buttons
$(".back a").button({
icons: {primary: "ui-icon-triangle-1-w"}
});
// checklist button rollover
$('#bottombox a').hover(
function () {
$('#bottombox').addClass("button").removeClass("nobutton");
}, function () {
$('#bottombox').addClass("nobutton").removeClass("button");
}
);
// start instance of countdown
$('.countdown').countdown({until: new Date(2014, 9-1, 21, 10), layout:
'<ul class="countdown-tabs"><li><a>{dn} <span>{dl}</span></a></li>' +
'<li><a>{hn} <span>{hl}</span></a></li>' +
'<li><a>{mn} <span>{ml}</span></a></li>' +
'<li class="last-child"><a>{sn} <span>{sl}</span></a></li></ul>'});
$('.bg-switcher input').change(function () {
// set background photo to value of photo-switcher
window.location.hash = $(this).attr('id');
var photo = "url('/images/countdown_" + $(this).attr('id') + ".jpg')";
$('#canvas').css('background-image', photo);
});
});
function setPhoto() {
if(window.location.hash === "" || window.location.hash === "#one") {
$('#one').attr("checked", "checked");
$(".bg-switcher").buttonset();
} else {
// grab the value of the URL hash
var urlHash = window.location.hash.substring(1);
// set background photo to value in URL hash
var urlPhoto = "url('/images/countdown_" + urlHash + ".jpg')";
$('#canvas').css('background-image', urlPhoto);
$('#' + urlHash).attr("checked", "checked");
$(".bg-switcher").buttonset();
}
};
I'm also calling:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="/js/jquery.countdown.js"></script>
<script type="text/javascript" src="/js/jquery.plugin.js"></script>
Any ideas on how to get it to count down? Appreciate it!
You don't look like calling the actual countdown script as indicated on the website you took the script from:
~2. Download and include the jQuery Countdown CSS and JavaScript in the head section of your page.
<link rel="stylesheet" type="text/css" href="css/jquery.countdown.css">
<script type="text/javascript" src="js/jquery.plugin.js"></script>
<script type="text/javascript" src="js/jquery.countdown.js"></script>
EDITED: Other than that, check the developer tool of your browser for errors and try to fix them all. They might not be related directly to this, but they may prevent the execution of the rest of the script.
Trying to use a jQuery plugin and it is not working and this error
'$' is undefined
keeps popping up. I am very new to Javascript and jQuery so please be as simple as possible
<script type="text/javascript" src="wpscripts/jquery-1.4.1.min.js"></script>
<!--[if IE 6]>
<script src="thumb-images/DD_belatedPNG_0.0.8a-min.js"></script>
<script>DD_belatedPNG.fix('#preview_inner div a');</script>
<![endif]-->
<script type="text/javascript">
$(document).ready(function () {
var outer = $("#preview_outer");
var arrow = $("#arrow");
var thumbs = $("#thumbs span");
var preview_pos;
var preview_els = $("#preview_inner div");
var image_width = preview_els.eq(0).width();
thumbs.click(function () {
preview_pos = preview_els.eq(thumbs.index(this)).position();
outer.stop().animate({ 'scrollLeft': preview_pos.left }, 500);
arrow.stop().animate({ 'left': $(this).position().left }, 500);
});
arrow.css({ 'left': thumbs.eq(0).position().left }).show();
outer.animate({ 'scrollLeft': 0 }, 0);
$("#preview_inner").css('width', preview_els.length * image_width);
});
</script>
That usually means that you have to import jquery at the top like this:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Edit: Here is the link for the updated version. I believe that this page will always update to the latest version of jQuery whereas my above answer won't: HERE
Check your script source path. It's likely not loading in.
If it's at the root of a site use:
<script type="text/javascript" src="/wpscripts/jquery-1.4.1.min.js"></script>
I see you have also tagged ASP.NET, so If it's in a control or somewhere that can be different for each page load, then use the following to have .Net figure out the actual relative path.
<script type="text/javascript" src="<%= ResolveClientUrl("~/wpscripts/jquery-1.4.1.min.js") %>"></script>
I see you are using WordPress.
You often are not able to define links with a relative path.
try using the php function "get_theme_root();" to get the theme root and navigate from there
I have a site with lots of images on one large page.
The easiest would be a Script that i could include, that automatically searches through that same page and uses all images larger than 100px to create a slideshow gallery from them.
Anyone knows such an easy script, that doesent need any programming skills?
I found this for a start:
jQuery get all images within an element larger than a specific size
To get all images larger that some size you can use something like this:
var allImages = $('img', yourDivElement)
var largeImages = allImages.filter(function(){
return ($(this).width() > 70) || ($(this).height() > 70)
})
Update:
After some more research, I found this the most fitting: Fancybox Gallery
It should be implemented on this page:
http://www.kathrinhoffmann.com/
It really depends on what is your favourite lightbox ("gallery opener"). Let's say thatyou like ShadowBox. It requires rel="shadowbox[gallery-name]" in which the gallery name is optional. The fun side of shadowbox is that lightbox instead of shadowbox will work as well.
What you then need to do is to add a link-tag around the images with this rel attribute.
var img = $("img"),
a = "<a href='",
b = "' rel='lightbox[",
galName = "chooseName",
c = "]'>";
img.each(function() {
var $this = $(this);
if ($this.width() > 100 || $this.height() > 100) {
$this.wrap(a + $this.attr("src") + b + galName + c);
}
});
Fiddle.
Have you tried doing something like this to get the original width and height of an image:
// loop through img elements
$('.img-class').each(function(){
// create new image object
image = new Image();
// assign img src attribute value to object src property
image.src = $(this).attr('src');
// function that adds class to image if width and height is greater that 100px
image.onload = function(){
// assign width and height values
var width = this.width,
height = this.height;
// if an image is greater than 100px width and height assign the
// string fancybox to image object className property
image.className = (width > 100 && height > 100) ? 'fancybox' : '';
}
});
#Bram Vanroy is almost right, but you need to take care about the real size (non affected by CSS or so) and about non loaded images (that's why my filters needs a callback to return the filtered images):
http://jsfiddle.net/coma/wh44u/3/
$(function() {
$('img').filterBiggerThan(100, function(big) {
console.log(big);
});
});
$.fn.filterBiggerThan = function (limit, callback) {
var imgs = [];
var last = this.length - 1;
this.each(function(i) {
var original = $(this);
var img = $('<img/>')
.appendTo('body')
.css({maxWidth: 'none'})
.load(function(event) {
if(img.width() > limit || img.height() > limit) {
imgs.push(original);
}
img.remove();
if(i >= last) {
callback(imgs);
}
});
img.attr('src', this.src);
});
};
Here you have another example:
http://jsfiddle.net/coma/NefFM/22/
Here you have a Fancybox gallery as Bram suggested:
http://jsfiddle.net/coma/NefFM/32/
Nothing stops you from wrapping your images (that you already found) with required markup and passing em to fancybox:
largeImages.each(function(){
$(this).wrap('<a></a>').parent().attr({'rel':'gallery', href: this.src});
});
$('a[rel=gallery]').fancybox();
You can see the working demo in this fiddle (beware I used body as root element for finding images in demo, you better add some class/attribute to the element that holds all the images you want to work with and use it instead).
Thanks,
I solved it like this:
I downloaded fancybox and added this code from the fancybox instructions at the bottom of my page at kathrinhoffmann.com :
<!-- Add jQuery library -->
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<!-- Add mousewheel plugin (this is optional) -->
<script type="text/javascript" src="/fancybox/lib/jquery.mousewheel-3.0.6.pack.js"></script>
<!-- Add fancyBox -->
<link rel="stylesheet" href="/fancybox/source/jquery.fancybox.css?v=2.1.4" type="text/css" media="screen" />
<script type="text/javascript" src="/fancybox/source/jquery.fancybox.pack.js?v=2.1.4"></script>
<!-- Optionally add helpers - button, thumbnail and/or media -->
<link rel="stylesheet" href="/fancybox/source/helpers/jquery.fancybox-buttons.css?v=1.0.5" type="text/css" media="s$
<script type="text/javascript" src="/fancybox/source/helpers/jquery.fancybox-buttons.js?v=1.0.5"></script>
<script type="text/javascript" src="/fancybox/source/helpers/jquery.fancybox-media.js?v=1.0.5"></script>
<link rel="stylesheet" href="/fancybox/source/helpers/jquery.fancybox-thumbs.css?v=1.0.7" type="text/css" media="sc$
<script type="text/javascript" src="/fancybox/source/helpers/jquery.fancybox-thumbs.js?v=1.0.7"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".fancybox").fancybox();
});
</script>
Then I included my own script:
<script type="text/javascript" src="/add_fancybox.js"></script>
which looks like this:
var img = $("img"),
a = "<a href='",
b = "' rel='group' class='fancybox'>";
img.each(function() {
var $this = $(this);
if ($this.width() > 50 && $this.height() > 50) {
$this.wrap(a + $this.attr("src") + b);
}
});
I have recently made the switch from HTML to XHTML... don't get me started on the "why" - let's just say it wasn't an option. Anyhoo...
This function worked fine in IE and FF when I was HTML, but now with XHTML I get the following error in FF:
heightElement is undefined
now here is the statement where I define heightElement
function revBars(isEFBOutput, isIXPPreview) {
if (!isIXPPreview) isIXPPreview = false;
var heightElement =
$('<div id="resizeDetectingElement" style="position:absolute; left:-9999999px height:1em;"> </div>')
.prependTo('body')
.get(0);
heightElement.currentHeight = heightElement.offsetHeight; // FireBug says the error is here.
insert();
window.onresize = refresh;
setInterval(
function() {
if (heightElement.currentHeight != heightElement.offsetHeight) {
heightElement.currentHeight = heightElement.offsetHeight; refresh();
}
}, 500);
function insert() {
var px = "px";
var color = (document.styleSheets[0].href.match("ftidStyleDay")) ? "black" : "white";
$revMarks = $('.RevMark').removeClass('RevMark').addClass('UnMarked');
if (!$revMarks.length) $revMarks = $('.UnMarked');
$revMarks.each(function() {
$('<div class="RevBar" />').css({
'background-color': color,
'width': '2px', 'position': 'absolute',
'left': (isEFBOutput && !isIXPPreview ? '.25em' : '-.75em'),
'height': this.offsetHeight,
'top': offset(this) + px
}).prependTo('body');
});
}
function refresh() { $('.RevBar').remove(); insert(); }
function offset(obj) {
var top = 0;
if (obj.offsetParent) {
do {
top += obj.offsetTop;
} while (obj = obj.offsetParent);
}
if (document.all && (!isEFBOutput || (isEFBOutput && isIXPPreview))) top -= 15;
return top;
}
}
any ideas why this is throwing an error in XHTML in FF? It still works in IE.
EDIT: Again, this code worked perfectly in FF and IE until I switched to XHTML. Firefox still creates a DOM for XHTML, right?
I rewrote some of your example, as you have errors and is incomplete with function calls that are not in the example:
$(document).ready( function(){
function revBars(isEFBOutput, isIXPPreview){
var test = "<div id=\"someElement\">whatever</div>";
$('body').prepend(test).get(0);
var heightElement = $('#someElement');
console.log( heightElement);
}
revBars();
});
At this point the heigthElement exists and the div is added to DOM.
Please provide correct problems in order to get them solved.
UPDATES
//var heightElement = $('<div id="resizeDetectingElement">whatever</div>').prependTo('body').get(0);
// this statement doesn't work
var heightElement = $('body').prepend('<div id="resizeDetectingElement">whatever</div>');
// this does
console.log(heightElement);
This is basically the same as first example.
The request that you made is to add a div before the element body and then get the first element of the body. The prependTo already returns the matched items so the get was irelevant. And you are attaching an element before the body so is normal that your variable will be empty.
Try my code and remove the downvote as not to many people had this kind of patience with your supercode.
UPDATE 2
This is an usage example for prepend() and prependTo().
<html>
<head>
<script type="text/javascript" src="../lib/jquery/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$(document).ready( function(){
$("#test_A").prepend('<div id=\'test_B\'>B</div>');
$("#test_C").prependTo( $('#test_A'));
var x = $('<div id="resizeDetectingElement">D</div>').prependTo('body').get(0);
console.log( x ); // returns the div
$(x).append('some text'); //works
});
</script>
</head>
<body>
<div id='test_A'>A</div>
<div id='test_C'>C</div>
</body>
</html>
I hope this will help to make your code work. USE $(heightElement) not just heightElement which is the div not the jQuery object.