jquery click-function is executed when page loads but not when clicked - javascript

I use jQuery to get the height of a div #img-copyright when the page is loaded, write in the var copyrightHeight and set the height of the div to 0.
When a different div is clicked, the function showImgCopyright() should set the max-height of the div #img-copyright to the content of the var.
I made two tries.
First one:
var copyrightHeight;
$(document).ready(function () {
copyrightHeight = $("#img-copyright").height();
console.log(copyrightHeight);
// just used to see if the height got written in the var - it is
$("img-copyright").css("max-height", 0);
$("#show-img-copyright").click(showImgCopyright());
function showImgCopyright() {
$("#img-copyright").css("max-height", copyrightHeight);
}
});
Second one:
var copyrightHeight;
$(document).ready(function () {
copyrightHeight = $("#img-copyright").height();
console.log(copyrightHeight);
// just used to see if the height got written in the var - it is
$("img-copyright").css("max-height", 0);
$("#show-img-copyright").click(function (){
$("#img-copyright").css("max-height", copyrightHeight);
});
});
In the first example the function is directly executed after the page is loaded and NOT when clicking the div (not the way I wanted it to be).
In the second example it works as I wanted it - the function just is executed when clicking the div.
But I don't get why.
How can I make it work with an extra function like in the first example?

Thank you very much.
I also found out, I forgot a # in the line $("img-copyright").css("max-height", 0);.
So the right code would be:
var copyrightHeight;
$(document).ready(function () {
copyrightHeight = $("#img-copyright").height();
$("#img-copyright").css("max-height", 0);
$("#show-img-copyright").click(showImgCopyright);
function showImgCopyright() {
$("#img-copyright").css("max-height", copyrightHeight);
}
});

Related

Creating a way to navigate back when using jQuery for AJAX

I am dynamically loading content into part of a page using jQuery .load().
It is working well, but I am having trouble building a way for the user to navigate back to the original content after the new content has been loaded.
I have created a 'close' icon with css which exists on the new page which is loaded, but I am not sure how to set up the jQuery / JavaScript in order for it to navigate the user back to the original state of that part of the page.
This is the relevant js:
// pages to load
var loadLudwig = "lw.html";
$("#work a:first-child").click(function() {
$("#work").fadeTo('slow', 0, function() {
$("#work").load(loadLudwig, function(){
$("#work").fadeTo('slow', 1);
});
});
});
// (& this part is working fine)
The relevant HTML (on the original page) is like this (its a grid of images embedded within anchor tags):
<section id="work">
...img and svg stuff
</section>
I tried many variations of:
$("#close-button").click(function() {
$("#work").fadeTo('slow', 0, function () {
$("#work").load('home.html #work', function() {
$("#work").fadeTo('slow', 1);
});
});
});
but this loads the content very strangely / some of the original functionality of #work is lost.
How do I get my close button to navigate back to the original state of #work?
In the jquery documentation for .load() is stated that:
Script Execution
When calling .load() using a URL without a suffixed selector
expression, the content is passed to .html() prior to scripts being
removed. This executes the script blocks before they are discarded. If
.load() is called with a selector expression appended to the URL,
however, the scripts are stripped out prior to the DOM being updated,
and thus are not executed. An example of both cases can be seen below:
Here, any JavaScript loaded into #a as a part of the document will
successfully execute.
1. $( "#a" ).load( "article.html" );
However, in the following case, script blocks in the document being
loaded into #b are stripped out and not executed:
1. $( "#b" ).load( "article.html #target" );
This is a probable cause for lack of functionality.
I'd also look into event binding. In your code examples you're using .click but if you are loading content or you are creating elements on-the-fly you should be favoring .on(). This method delegates events instead of just binding them to a DOM node.
I'd recommend you reading the whole article.
EDIT:
Here is a quick n'dirty way of achieving the effect
// pages to load
var loadLudwig = "lw.html",
$ludwig,
$work = $('#work'),
$workContent = $work.children(),
$closeButton = $("#close-button");
$work.find('a:first-child').click(function() {
$work.fadeTo('slow', 0, function() {
//Here is the tricky part
//Detaching keeps all the jQuery data on the elements
$workContent.detach();
//The first time, load the content,
//if the content is already loaded
//append it to the container
if(!$ludwig){
$work.load(loadLudwig, function(){
//Save the content in a var
//so you can reuse it later
$ludwig = $work.children();
$work.fadeTo('slow', 1);
});
} else {
$ludwig.appendTo($work);
$work.fadeTo('slow', 1);
}
});
});
$closeButton.click(function() {
$work.fadeTo('slow', 0, function () {
//Remove the old content, don't worry
//because is stored in $ludwig
$work.children().detach();
//Instead of reloading the content, just
//attach the fragment again
$workContent.appentTo($work);
$work.fadeTo('slow', 1);
});
});
You probably need to save the html somewhere. For example:
// Top of file
var oldHTML = "";
// Lots of stuff...
$("#work a:first-child").click(function() {
$("#work").fadeTo('slow', 0, function() {
// Store the old html
oldHTML = $("#work").html();
$("#work").load(loadLudwig, function(){
$("#work").fadeTo('slow', 1);
});
});
});
// Code for the close button
$("#close-button").click(function() {
$("#work").fadeTo('slow', 0, function () {
$("#work").html(oldHTML).fadeIn("slow");
});
});
Alternatively, instead of replacing the html, you could create another child. Of course, you might have to slightly change your markup.
<section id="work">
<div id="oldHTML">
...img and svg stuff
</div>
<div id="newSection" style="display:none;">
</div>
</section>
Then replace $("#work") with $("#oldHTML") in your first piece of code like so:
$("#oldHTML a:first-child").click(function() {
$("#oldHTML").fadeTo('slow', 0, function() {
$("#oldHTML").hide();
$("#newSection").load(loadLudwig, function(){
$("#newSection").show().fadeTo('slow', 1);
});
});
});
// Code for the close button
$("#close-button").click(function() {
$("#newSection").fadeTo('slow', 0, function () {
$("#newSection").hide();
$("#work").fadeIn("slow");
});
});

jQuery Toggle one element at time with closing/hiding

I'm a Js beginner, and here's my code (the pics are not the same, but it's exactly what I want) :
$('#img-expand').click(function () {
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
$("#work-info_2").slideToggle("slow");
});
Look at this : http://jsfiddle.net/vk7AE/1/
I would like that when I click on an image, the text associated with this one appears, and that if I click on the other image, the preceding text disappears, and that the new text associated with the clicked image appears in its place.
In fact, I would like that people can open only one text at the same time.
I hope that you will include/understand my problem, and that you will be able to help me.
Regards.
DEMO
$('#img-expand').click(function () {
$('[id^="work-info"]').hide();
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
$('[id^="work-info"]').hide();
$("#work-info_2").slideToggle("slow");
});
attribute-equals-selector
^ attribute-starts-with-selector
Description: Selects elements that have the specified attribute with
a value beginning exactly with a given string.
$('[id^="work-info"]'); select all elements with id starting with work-info
updated after OP's comment
DEMO
$('#img-expand').click(function () {
$('[id^="work-info"]').not('#work-info').hide();
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
$('[id^="work-info"]').not('#work-info_2').hide();
$("#work-info_2").slideToggle("slow");
});
.not()
$('#img-expand').click(function () {
var slide = $("#work-info").is(":visible");
$(".part-body-opacity p").slideUp();
if(!slide)
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
var slide = $("#work-info_2").is(":visible");
$(".part-body-opacity p").slideUp();
if(!slide)
$("#work-info_2").slideToggle("slow");
});
http://jsfiddle.net/vk7AE/5/

hide one div when another is showing in jQuery?

I am trying to hide a div when another one is visible.
I have div 1 and div 2.
If div 2 is showing then div 1 should hide and if div 2 is not showing then div 1 should be visible/unhide.
The function would need to be function/document ready upon page load.
I've tried this but I'm not having any luck, can someone please show me how I can do this.
<script>
window.onLoad(function () {
if ($('.div2').is(":visible")) {
$(".div1").fadeOut(fast);
} else if ($('.div2').is(":hidden")) {
$('.div1').fadeIn(fast);
}
});
</script>
Add a class of hidden to each div, then toggle between that class using jQuery. By the way, window.onload is not a function, it expects a string like window.onload = function() {}. Also, put fast in quotations. I don't know if that's required, but that's how jQuery says to do it.
<div class="div1"></div>
<div class="div2 hidden"></div>
.hidden { display: none }
$(document).ready(function() {
if($(".div1").hasClass("hidden")) {
$(".div2").fadeIn("fast");
}
else if($(".div2").hasClass("hidden")) {
$(".div1").fadeIn("fast");
}
});
You should pass a string to the .fadeIn() and .fadeOut() methods.
Instead of .fadeIn(fast) it'll be .fadeIn("fast"). Same for .fadeOut().
And in general since you're already using jQuery it's better to wrap your code like this:
$(function () {
// Code goes here
});
It looks like you're using jquery selectors (a javascript library). If you're going to use jquery make sure the library is loaded properly by including it in the document header (google makes this easy by hosting it for you <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>)
With jQuery loaded you can do it like this
$(document).ready(function(){
if ($('.div1').is(":visible")) {
$('div2').hide();
}
else if ($('.div2').is(":visible")) {
$('div1').hide();
}
});
WORKING EXAMPLE: http://jsfiddle.net/HVDHC/ - just change display:none from div 2 to div 1 and click 'run' to see it alternate.
You can use setTimeout or setInterval to track if these divs exists
$(function() {
var interval = window.setInterval(function() {
if($('#div2').hasClass('showing')) {
$('#div1').fadeOut('fast');
}
if($('#div2').hasClass('hidden')) {
$('#div1').fadeIn('fast');
}
}, 100);
// when some time u don't want to track it
// window.clearInterval(interval)
})
for better performance
var div1 = $('#div1')
, div2 = $('#div2')
var interval ....
// same as pre code

offset is undefined in Header Fixed

I now have a code to fixed the header of my tables and it works fine. But this function have a warning :
Error: TypeError: $(...).offset(...) is undefined
My code (I use bootstrap):
function goheadfixed(classtable) {
$(classtable).wrap('<div class="fix-inner">');
$('.fix-inner').wrap('<div class="fix-outer" style="position: relative;"></div>'); //this is relative cause the header will be absolute
$('.fix-outer').append('<div class="fix-head"></div>');
$('.fix-head').prepend($('.fix-inner').html()); // agrego la tabla
$('.fix-head table').find('caption').remove();
//$('.fix-head table').removeAttr('style');
$('.fix-head table').css('width','100%');
$('.fix-head').css('width', $('.fix-inner table').outerWidth(true)+'px');
$('.fix-head').css('height', $('.fix-inner table thead').outerHeight(true)+'px');
var ithead = parseInt($('.fix-inner table thead').offset().top);
var divfix = parseInt($('.fix-inner').offset().top);
var itop = ithead-divfix;
$('.fix-head').css({'position':'absolute', 'overflow':'hidden', 'top': itop+'px', 'left':0, 'z-index':100 });
$(window).scroll(function () {
var vscroll = $(window).scrollTop();
if(vscroll >= ithead)
$('.fix-head').css('top',(vscroll-divfix)+'px');
else
$('.fix-head').css('top', itop+'px');
});
/* If the windows resize */
$(window).resize(goresize);
}
function goresize() {
$('.fix-head').css('width', $('.fix-inner table').outerWidth(true)+'px');
$('.fix-head').css('height', $('.fix-inner table thead').outerHeight(true)+'px');
}
I call my function:
goheadfixed('table.fixed');
Then when I put other code javascript below, my code doesn't work but when put above, it works fine! :
How can I delete this warninng?
EDIT (adding details posted as an answer):
Oh. I'm sorry, I forgot say the "warning" only appears when I don't use the function.
If I call the funcion goheadfixed('table.fixed'); all right, but if I don't call this function, the warning is showed.
On line 14, $('.fix-inner table thead') is either referring to elements that do not exist or are hidden. It sounds as if you are finding at least one element with display:none set, and it's returning an undefined number because of that.
To fix this, you can add the visible selector $("thead:visible") with each element.

JScrollPane Plugin - Reinitialize on Collapse

I'm trying to get JScrollPane to reinitialize on expand/collapse of my accordion found here. You can demo the accordion by clicking on one of the parents (Stone Tiles, Stone Sinks, Stone Wall Clading, etc).
Right now I set it as a click event using the following JQuery...
var pane = $('.menuwrap')
pane.jScrollPane();
var api = pane.data('jsp');
var i = 1;
$("ul#widget-collapscat-5-top > li.collapsing").click(function() {
$(this).delay(3000);
api.reinitialise();
});
It seems to work when you click the parent the second time, but not the first. I have no idea why but I went into trying to edit the JS for the accordion so that I can add this function when the collapse is complete (as opposed to trying to do this click workaround). The collapse JS can be viewed here.
I tried to add the JS for the reinitialize function here, but I think I'm not doing something properly.
May you point me in the right direction?
Thanks!
The api.reinitialise() is working properly. What is happening is that it updates the size when you click, and at this moment the element is not expanded yet. You may notice that if you expand, colapse and expand again the same section, nothing happens. But if you expand one and then click another one, the ScrollPane will adjust to the size of the first expanded element.
You can solve this with events: place $(this).trigger('colapseComplete') when the colapse ends. Then you can use:
//Listening to the colapseComplete event we triggered above
$("#widget-collapscat-5-top > li.collapsing").on('colapseComplete', function() {
api.reinitialise();
});
Maybe you can alter the addExpandCollapse function to call the reinitialise function at the end of each of its click actions this way :
function addExpandCollapse(id, expandSym, collapseSym, accordion) {
jQuery('#' + id + ' .expand').live('click', function() {
if (accordion==1) {
var theDiv = jQuery(this).parent().parent().find('span.collapse').parent().find('div');
jQuery(theDiv).hide('normal');
jQuery(this).parent().parent().find('span.collapse').removeClass('collapse').addClass('expand');
createCookie(theDiv.attr('id'), 0, 7);
}
jQuery('#' + id + ' .expand .sym').html(expandSym);
expandCat(this, expandSym, collapseSym);
api.reinitialise(); // HERE
return false;
});
jQuery('#' + id + ' .collapse').live('click', function() {
collapseCat(this, expandSym, collapseSym);
api.reinitialise(); // and HERE
return false;
});
}
and to be on a safer side, make sure you have the var api = pane.data('jsp'); line before the above piece of code anywhere in the file.

Categories

Resources