A the end of my index.html file I'm including two script files. One of files handles loading page content with jquery. The other file handles manipulating a tabbed content area on my home page, also jquery. If I put the file for the tabbed content area after the file for the ajax page load file, then tabs work but the ajax for the page load does not work. If I reverse the order of those files, then the page load ajax works but not the tabs. What could be causing this?
Here's the file for the tabbed content:
$(document).ready(function (){
initialize();
});
function initialize() {
//Click on nav to load external content through AJAX
// $('#topnav a').click(function(e){
// e.preventDefault();
// $('#pages').load( e.target.href + ' #loadcontent'); //pages finished loading
// }); //clicked on nav
$(function() {
$("#tabedarea").organicTabs();
$("tabedarea").organicTabs({
"speed": 200
});
});
}
(function($) {
$.organicTabs = function(el, options) {
var base = this;
base.$el = $(el);
base.$navtabs = base.$el.find(".navtabs");
base.init = function() {
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Accessible hiding fix
$(".hidetabs").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
base.$navtabs.delegate("li > a", "click", function() {
// Figure out current list via CSS class
var curList = base.$el.find("a.current").attr("href").substring(1),
// List moving to
$newList = $(this),
// Figure out ID of new list
listID = $newList.attr("href").substring(1),
// Set outer wrapper height to (static) height of current inner list
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Fade out current list
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Fade in new list on callback
base.$el.find("#"+listID).fadeIn(base.options.speed);
// Adjust outer wrapper to fit new list snuggly
//var newHeight = base.$el.find("#"+listID).height();
//$allListWrap.animate({
// height: newHeight
//});
// Remove highlighting - Add to just-clicked tab
base.$el.find(".navtabs li a").removeClass("current");
$newList.addClass("current");
});
}
// Don't behave like a regular link
// Stop propegation and bubbling
return false;
});
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);
And here's the file for the page load ajax:
// remap jQuery to $
(function($){})(window.jQuery);
/* trigger when page is ready */
$(document).ready(function (){
initialize();
});
function initialize() {
//Click on nav to load external content through AJAX
$('#topnav a, #bottomnav a').not('#bottomnav #fbcallus a').click(function(e){
e.preventDefault();
$('#pages').load( e.target.href + ' #loadcontent'); //pages finished loading
}); //clicked on nav
//handle AJAX for left nav
}
You're creating global functions with the same name initialize change the names of those or just one. The one that's loaded afterwards overrides the first
The problem is having both the functions the same name. Use two different names for the functions.
Then you don't need to add two page load handlers. Add a single page load handler in the latter script and call the two methods in it.
suppose your two functions are initialize() and init2() then at the latter js file use
$(document).ready(function () {
initialize();
init2();
});
Related
I replaced content from index.htm with content from project.htm. When you click on a#front it is linked on project.htm and it dynamically loads (replaces) the new content. But I have an issue with how to execute javascript that I'm loading with new content. To load script I used function getScript. Here is the function that I'm using to load new content and script:
$(document).ready(function() {
$('a#front').click(function() {
var toLoad = $(this).attr('href')+' #content';
$('#content').hide("drop", { direction: "left" }, "slow", loadContent);
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);
function loadContent() {
$('#content').load(toLoad ,'',showNewContent())
}
function showNewContent() {
$('#content').show("drop", { direction: "right" }, "slow");
$.getScript('js/project.js');
}
return false;
});
});
Javascript that I loaded when I loaded new content only worked if I had alert at the top or this way. But when I try to load more complex content (insted just text I put div, headings etc) it doesnt work:
$.ajax({
success: function(data) {
$('a#link').click(function() {
$("p").css("color","white");
});
}
});
Can you help me with this or maybe you have some different solution?
I solve this problem and menaged to load content from new file and also javascript for that. Notice that in new file I need to have content wrapped into div with ID content and I load it into div in native document, with the same name - content.
Here is how I load new content and how I call new javascript files using getScript function:
$('a#front').click(function() {
var toLoad = $(this).attr('href')+' #content';
$('#content').hide("drop", { direction: "left" }, "slow", loadContent);
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);
function loadContent() {
$('#content').load(toLoad ,'',showNewContent())
}
function showNewContent() {
$('#content').show("drop", { direction: "right" }, "slow");
$.getScript('js/project.js');
$.getScript('js/section.js');
$.getScript('js/carousel.js');
}
return false;
});
To force loaded javascript execution I used setTimeout function. For example this is how looks code inside carousel.js file which activate carousel:
$(document).ready(function($) {
setTimeout(function(){
//run carousel
$("#owl-example").owlCarousel();
}, 100); });
How it works you can see here
Edit: I guess part of this is an issue of me being inexperienced with Drupal. I added a javascript file to site.info, so that it will be added to every page. This is all the file contains:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
When the site loads, it gets compiled into this larger script, which looks like this in the debugger:
(function ($) {
Drupal.behaviors.titlebar = {
init: function(context, settings) {
// Using percentage font size to easily increase/decrease page font size
var baseFontSize = 100;
$('.pgc-font-size a').click(function() {
if($(this).hasClass('increase')) {
if(baseFontSize < 150)
baseFontSize += 20;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
} else {
if(baseFontSize > 70)
baseFontSize -= 10;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
}
});
// Print button
$('.pgc-print a').click(function() {
window.print();
})
}
};
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.titlebar.init();
});;
(function ($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function(){
if($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
;
You can see my little script at the bottom there. It says there's something wrong with the first line, but I'm not sure what the problem is. What change would I need to make to my javascript file to make sure it compiles right?
I'm probably overlooking a really simple type, but I can't see what's wrong with my jQuery.
This is the part that's not working:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.website.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
I have jQuery on my site, I know I do because this it's used earlier in the code with no problem. The error is showing in the debugger on the first line, '$("#ct100_btnSearch001").on("click", function(){ '. Here is a larger section of the script page:
(function($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function() {
if ($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function($) {
$("#ctl00_btnSearch001").on("click", function() {
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);;
Try to install jQuery update Module.
If you are using Drupal 6, you are not be able to use on function.
One option is to include your custom version of jQuery in your page.tpl.php, another option (not recommended) is to use live, but now is deprecated.
You can bind a function to an event use two way:
1.use bind() method and the event name as the first argument
$( "#foo" ).bind( "click", function() {
alert( "User clicked on 'foo.'" );
});
or
2.just use the event method
$( "#foo" ).click( function() {
alert( "User clicked on 'foo.'" );
});
The problem of your code is that there isn't a on event.
ref http://api.jquery.com/category/events/mouse-events/
If ctl00_btnSearch001 is a correct id for what ever you are trying to click. Try changing it to this:
(function ($){
$(document).on("click", "#ctl00_btnSearch001", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
EDIT: This software package is the full and undoctored version of what I'm trying to fix here. The problem is in the /data/renderpage.js script. Feel free to examine this before continuing.
https://github.com/Tricorne-Games/HyperBook
I really appreciate all the help guys!
=
I am polishing a jQuery script to do the following in a rigid sequence...
Fade out the text.
Shrink the size of the container div.
Preload the remote HTML ///without showing it yet!///
Open the size of the container div.
Fade in the new remote HTML.
I do not mind if steps 1 and 2, 4 and 5 are combined to be one whole step (fade/resize at the same time). It's when the new HTML is loaded it interrupts the entire animation, even from the beginning.
The idea is that I do not want my remote HTML to show until after the animation renders right. I want the original text to fade out and the container div close up, then, behind the scenes, ready the text of the new HTML, and then have the container div open up and fade the new text in.
It seems when I call the load(url) function, it instantaneously loads the page up, and the animations are still running (like the new HTML ends up fading out, only to fade back in, and not the original text out and then the new one in). Either that, or the whole function is calling each line at the same time, and it's disrupting the page-changing effect I want.
Here's my current script setup...
$(document).ready(function() {
// Start-Up Page Load (Cover, ToC, etc.)
$('#content').load('pages/page1.htm');
// Navigating Pages
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href');
$('#content_container').animate({height: 'hide'}, 500);
$('#content').fadeTo('slow', 0.25);
$('#content').load(ahref);
$('#content').css({opacity: 0.0});
$('#content').fadeTo('slow', 1.0);
$('#content_container').animate({height: 'show'}, 500);
return false;
});
});
What is it wrong I'm doing here? I have used the delay() function on every one of those steps and it doesn't solve the problem of holding back the new text.
jQuery objects can provide a promise for their animation queues by calling .promise on the jQuery element.
You can wait on one or more of these to complete using $.when() and then perform other operations.
The following does a fade out and slide up in parallel with the load, then (only when the animations complete), slides it down then fades it in (in sequence):
$(document).on('click', 'a', function (e) {
e.preventDefault();
var ahref = $(this).attr('href')
var $container = $('#content_container');
var $content = $('#content');
// Slide up and fadeout at the same time
$container.animate({
height: 'hide'
}, 500);
$content.fadeOut();
// Load the content while fading out
$('#content').load(ahref, function () {
// Wait for the fade and slide to complete
$.when($container.promise(), $content.promise()).then(function () {
// Slide down and fadein (in sequence)
$container.animate({
height: 'show'
}, 500, function () {
$content.fadeTo('slow', 1.0);
});
});
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pffm1tnb/3/
The only issue with this version is that the load may complete faster than the fadeout/slideup and show the new data too early. In this case you want to not use load, but use get (so you have control over when to insert the new content):
// Load the content while fading out
$.get(ahref, function (data) {
// Wait for the fade and slide to complete
$.when($container.promise(), $content.promise()).then(function () {
$content.html(data);
// Slide down and fadein (in sequence)
$container.animate({
height: 'show'
}, 500, function () {
$content.fadeTo('slow', 1.0);
});
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pffm1tnb/4/
Notes:
return false from a click handler does the same as e.stopPropagation() and e.preventDefault(), so you usually only need one or the other.
I started with the JSFiddle from #Pete as no other sample was handy. Thanks Pete.
Update:
Based on the full code now posted, you are returning full pages (including header and body tags). If you change your code to .load(ahref + " #content" ) it will extract only the part you want. This conflicts with the second (better) example I provided which would need the pages returned to be partial pages (or extract the required part only).
Additional Update:
As $.get also returns a jQuery promise, you can simplify it further to:
$.when($.get(ahref), $container.promise(), $content.promise()).then(function (data) {
$content.html(data);
// Slide down and fadein (in sequence)
$container.animate({
height: 'show'
}, 500, function () {
$content.fadeTo('slow', 1.0);
});
});
The resolve values from each promise passed to $.when are passed to the then in order, so the first parameter passed will be the data from the $.get promise.
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pffm1tnb/11/
The issue is because you're not waiting for the hide animations to finish before loading the content, or waiting for the content to load before starting the show animations. You need to use the callback parameters of the relevant methods. Try this:
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href'),
$content = $('#content'),
$contentContainer = $('#content_container');
$contentContainer.animate({ height: 'hide'}, 500);
$content.fadeTo('slow', 0.25, function() {
// animation completed, load content:
$content.load(ahref, function() {
// load completed, show content:
$content.css({ opacity: 0.0 }).fadeTo('slow', 1.0);
$contentContainer.animate({ height: 'show' }, 500);
});
});
});
Note that for the effect to work the most effectively on the UI you would need to perform the load() after the animation which takes the longest to complete has finished.
Instead of using the load() function, you can use the get() function and its callback paramater to save the HTML into a variable before actually putting it into the element with html().
After doing all the animations to fade out and close the old box (and maybe inside an animation-finished callback function) you'll want to use something like the following:
$.get(ahref, function(data) {
// JQuery animation before we want to see the text.
$('#content').html(data); // actually inserts HTML into element.
// JQuery animation to fade the text in.
});
Using a bunch of the code everyone posted here, I rewrote the segment I originally had to follow suit. This is now my working result.
$(document).ready(function() {
// Start-Up Page Load (Cover, ToC, etc.)
$('#content').load('pages/page1.htm');
// Navigating Pages
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href');
$('#content').fadeTo('slow', 0.0)
$('#content_container').animate({height: 'hide'}, 500, function(){
$('#content').load(ahref + '#content', function(){
$('#content_container').animate({height: 'show'}, 500, function(){
$('#content').fadeTo('slow', 1.0);
});
});
});
return false;
});
});
You can use deferred or callbacks function
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href');
var dfd1 = $.Deferred();
var dfd2 = $.Deferred();
var dfd3 = $.Deferred();
var dfd4 = $.Deferred();
$('#content_container').animate({height: 'hide'}, 500, function(){
dfd1.resolve();
});
dfd1.done(function() {
$('#content').fadeTo('slow', 0.25, function() {
dfd2.resolve();
});
});
dfd2.done(function() {
$('#content').load(ahref, function() {
$('#content').css({opacity: 0.0});
dfd3.resolve();
});
});
dfd3.done(function() {
$('#content').fadeTo('slow', 1.0, function() {
dfd4.resolve();
});
});
dfd4.done(function() {
$('#content_container').animate({height: 'show'}, 500);
});
return false;
});
So I'm using the History.js plugin to load pages in my Wordpress theme via AJAX. I've been successful in doing so and have the entire loading feature working fine. However, I have many scripts working in the same file and they of course do not get loaded on the state change.
Here's (a very brief) version of my functions.js file to explain:
(function($){})(window.jQuery);
$(document).ready(function() {
/* THIS IS CODE RELATIVE TO MY HOME PAGE ONLY */
$projects = $("#projects");
$projects.append($(".contact"));
$projects.isotope({
itemSelector : '.item',
layoutMode : 'masonry'
});
/* END PREVIOUS BLOCK */
/* BEGIN HISTORY.JS IMPLEMENTATION */
var History = window.History,
State = History.getState();
$('.nav a, .leftHold a').on('click', function(event) {
event.preventDefault();
var path = $(this).attr('href');
var title = $(this).text();
History.pushState('ajax', title, path);
});
History.Adapter.bind(window, 'statechange', function() {
load_site_ajax();
});
function load_site_ajax() {
State = History.getState();
$('body, html').animate({ scrollTop : 0 }, 250, function() {
$("#article").animate({ left : -1*$(window).width() }, 250, function() {
$(this).load(State.url + ' #article', function() {
$(".nav li").each(function() {
$(this).removeClass("current_page_item").removeClass("current_page_parent").removeClass("current_page_ancestor");
}).promise().done(function() {
$(".nav a").each(function() {
if(State.title.indexOf($(this).text()) != -1) {
$(this).parent().addClass('current_page_item');
return false;
}
});
});
}).promise().done(function() { $(this).css("left", $(window).width()).animate({ left : 0 }, 250); });
});
});
}
/* END HISTORY.JS */
});
I load this functions.js file at the end of my document, just before the closing body tag. I can tell that whenever I change browser states, the code in $(document).ready(); doesn't run again, therefore Isotope and none of my other Javascripts load again.
QUESTION:
How should I ensure that the code in functions.js runs every time the pushstate is initiated by History.js?
It sounds like you'll need to execute the ready code again. Wrap your initialization code in a function:
$(document).ready(initializePage);
function initializePage() {
/* THIS IS CODE RELATIVE TO MY HOME PAGE ONLY */
...
}
And then, when "statechange" fires, you can call initializePage() again.
You will also need to make sure the History code only runs once, so put that code in a separate function:
$(document).ready(setupHistory);
function setupHistory() {
/* BEGIN HISTORY.JS IMPLEMENTATION */
var History = window.History,
State = History.getState();
});
....
}
I used a flowplayer tutorial to make some ajax tabbed content but the it doesn't use any kind of a loading indication in between content load. How can I add that to this script? http://pastebin.com/PebcJspn
<script>
$(function() {
$(".feed-tabs ul").tabs("div.feeds > div", {
effect: 'fade',
onBeforeClick: function(event, i) {
// get the pane to be opened
var pane = this.getPanes().eq(i);
// only load once. remove the if ( ... ){ } clause if you want the page to be loaded every time
if (pane.is(":empty")) {
// load it with a page specified in the tab's href attribute
pane.load(this.getTabs().eq(i).attr("href"));
}
}
});
});
</script>
You can try add an element with a loading gif before call the method .load() and it will be removed when .load() inserts the html result.
<script>
$(function() {
$(".feed-tabs ul").tabs("div.feeds > div", {
effect: 'fade',
onBeforeClick: function(event, i) {
// get the pane to be opened
var pane = this.getPanes().eq(i);
// only load once. remove the if ( ... ){ } clause if you want the page to be loaded every time
if (pane.is(":empty")) {
//add this
pane.append("<img src='http://mentalized.net/activity-indicators/indicators/ilcu/roller.gif'/>")
// load it with a page specified in the tab's href attribute
pane.load(this.getTabs().eq(i).attr("href"));
}
}
});
});
</script>