1

I am developing a website that parses rss feeds and displays them based on category. You can view it here: http://vitaminjdesign.com/adrian

I am using tabs to display each category. The tabs use ajax to display a new set of feeds when they are clicked.

I am also using two other scripts- One called equalheights, which re-sizes all of the heights to that of the tallest item. And the other script I am using is called smart columns, which basically resize your columns so it always fills the screen.

The first problem I am having is when you click a new tab (to display feeds within that category). When a new tab is clicked, the console shows a jQuery error:

$(".block").equalHeights is not a function
[Break On This Error] $(".block").equalHeights(); 

The main problem is that each feed box fills up the entire screen's width (after you click on a tab), even if there are multiple feed boxes in that category.

MY GUESS - although all of the feeds (across all tabs) are loaded on pageload, when a new tab is selected, both jQuery scripts need to be run again. any ideas on how I can make this work properly?

One thing to note - I used the ajaxSuccess method for making equalHeights work on the first page...but it wont work after a tab is clicked.

My jQuery code for the tabs are below:

$(".tab_content").hide(); //Hide all content
        $("ul.tabs li:first").addClass("active").show(); //Activate first tab
        $(".tab_content:first").show(); //Show first tab content

        $("#cities li:nth-child(1)").addClass('zebra');
        $("#column li ul li:nth-child(6)").addClass('zebra1');


        //On Click Event
        $("ul.tabs li").click(function() {

            $("ul.tabs li").removeClass("active"); //Remove any "active" class
            $(this).addClass("active"); //Add "active" class to selected tab
            $(".tab_content").hide(); //Hide all tab content

            var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
            $(activeTab).fadeIn(); //Fade in the active ID content
            $(".block").equalHeights();
            return false;
        });

Thanks to Macy (see answer below), I have brought my jQuery script to the following: (still does not work)

$(document).ajaxSuccess(function(){
        var script = document.createElement('script');
        script.src = 'js/equalHeight.js';
        document.body.appendChild(script);
        equalHeight($(".block"));
user229044
  • 232,980
  • 40
  • 330
  • 338
JCHASE11
  • 3,901
  • 19
  • 69
  • 132

4 Answers4

3

I found some small problems in your code. I am not sure that my suggestions will solve all the problems, but I decide to describe my first results here.

1) You should remove comma before the '}'. Currently the call look like $("#column").sortable({/**/,});

2) The function equalHeight is not jQuery plugin. It is the reason why the call $(".block").equalHeights(); inside your 'click' event handler follows to the error "$(".block").equalHeights is not a function" which you described. You should change the place of the code to equalHeight($(".block")); like you use it on other places.

3) The script http://vitaminjdesign.com/adrian/js/equalHeight.js defines the function equalHeight only and not start any actions. Once be loaded it stay on the page. So you should not load it at the end of every ajax request. So I suggest to reduce the script

$(document).ajaxSuccess(function(){
    var script = document.createElement('script');
    script.src = 'http://vitaminjdesign.com/adrian/js/equalHeight.js';
    document.body.appendChild(script);
    equalHeight($(".block"));

    $("a[href^='http:']:not([href*='" + window.location.host + "'])").each(function() {               
        $(this).attr("target", "_blank");
    });
});

to

$(document).ajaxSuccess(function(){
    equalHeight($(".block"));

    $("a[href^='http:']:not([href*='" + window.location.host + "'])").each(function() {               
        $(this).attr("target", "_blank");
    });
});

4) I suggest to change the code of http://vitaminjdesign.com/adrian/js/equalHeight.js from

function equalHeight(group) {
   tallest = 0;
   group.each(function() {
      thisHeight = $(this).height();
      if(thisHeight > tallest) {
         tallest = thisHeight;
      }
   });
   group.height(tallest);
}

to

function equalHeight(group) {
   var tallest = 0;
   group.each(function() {
      var thisHeight = $(this).height();
      if(thisHeight > tallest) {
         tallest = thisHeight;
      }
   });
   group.height(tallest);
}

to eliminate the usage of global variables tallest and thisHeight. I recommend you to use JSLint to verify all your JavaScript codes. I find it very helpful.

5) I recommend you to use any XHTML validator to find some small but sometime very important errors in the markup. Try this for example to see some errors. The more you follow the XHTML standards the more is the probability to have the same results of the page in different web browsers. By the way, you can dramatically reduce the number of the errors in your current code if the scripts included in the page will be in the following form

<script type="text/javascript">
//<![CDATA[
/* here is the JavaScript code */
//]]>
</script>

I didn't analysed the full code but I hope that my suggestions will solve at least some of problems which you described in your question.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • wow thank you, let me look into all this tonight and will be back with some feedback tomorrow. THANKS! – JCHASE11 Feb 03 '11 at 23:32
0

Essentially, when you add a new element to the document, the equalheights script has not attached its behavior to that new element. So, the "quick fix", is probably to re-embed the equalheights script after an ajax request has completed so that it re-attaches itself to all elements on the page, including the elements you just added.

Before this line: $(".block").equalHeights(); , add a line of script which re-embeds/re-runs your equalheights script.

$.getScript('<the location of your equalHeightsScript>'); 
$.getScript('<the location of your smartColumnsScript>');
$(".block").equalHeights();

or

var script = document.createElement('script');
script.src = '<the location of your script>';
document.body.appendChild(script);

A better solution would be to upgrade the plugin so it takes advantage of live. However, I'm not up to that at the moment :)

Macy Abbey
  • 3,877
  • 1
  • 20
  • 30
  • what kind of line of code will rerun that script after ajax is complete (everytime)? Currently I have: $(document).ajaxSuccess(function(){ – JCHASE11 Jan 30 '11 at 19:24
  • The `.live()` method has been around for 2 years, and it really has nothing to do with DOM changes. Overall it's pretty useless with respect to calling a plugin against newly added elements. – user113716 Jan 30 '11 at 19:34
  • Its not just equalheights that need to be loaded again after a tab is clicked. The function smartColumns needs to be loaded as well. I need a solution that will rerun both of these functions after a tab is clicked – JCHASE11 Jan 30 '11 at 19:37
  • 1
    @patrick thanks Patrick, modified to reflect your statements. – Macy Abbey Jan 30 '11 at 20:38
  • $.getScript(); $.getScript(); – Macy Abbey Jan 30 '11 at 20:40
  • $.getScript(<'js/smartColumn.js'>); $.getScript(<'js/equalHeight.js'>); equalHeight($(".block")); – JCHASE11 Jan 31 '11 at 02:30
  • the above spits out an error that reads invalid XML name [Break On This Error] $.getScript(<'js/smartColumn.js'>); index – JCHASE11 Jan 31 '11 at 02:30
  • remove the < and > those were indicators of a token you need to replace – Macy Abbey Jan 31 '11 at 02:58
  • ok. Check out the site now. This causes some serious problems - The site continues to load and says "waiting for cache"...doesn't seem to be working. – JCHASE11 Jan 31 '11 at 03:06
  • $.getScript is an ajax operation. You have two ajax operations which get run everytime an ajax operation is successful. Infinite loop. Check up above for keeping your code placement but losing the ajax embed. – Macy Abbey Jan 31 '11 at 05:52
  • if I switched $(document).ajaxSuccess(function(){ to $(document).ready(function(){ it will still not work... – JCHASE11 Jan 31 '11 at 18:26
  • this doesnt seem to work either (and I think this is the correct syntax): $(document).ready(function(){ $.getScript('js/equalHeight.js', function() { equalHeight($(".block")); }); }); – JCHASE11 Jan 31 '11 at 18:28
  • and the document.ready way won't work for when ajax requests or javascript adds additional elements to the page after load. – Macy Abbey Jan 31 '11 at 18:30
  • If I cant use a doc ready or ajax success, what should I do here? – JCHASE11 Jan 31 '11 at 20:07
  • Use the ajax success but embed the scripts by manually creating script elements and appending them to the document. I edited my answer to have an example of that. – Macy Abbey Jan 31 '11 at 21:22
  • I really appreciate all of your help, but it is still not working. Please see the link again as all of the code was just uploaded. I am still receiving the error when I switch tabs: $(".block").equalHeights is not a function [Break On This Error] $(".block").equalHeights(); – JCHASE11 Feb 01 '11 at 03:34
0

Some Error Here

$("ul.tabs li").click(function() {
            $("ul.tabs li").removeClass("active"); //Remove any "active" class
            $(this).addClass("active"); //Add "active" class to selected tab
            $(".tab_content").hide(); //Hide all tab content
            .
            .
            .
        });

Should be re-written like this

$("ul.tabs li").click(function() {
            $(this).addClass("active").Siblings("li").removeClass("active");; //Remove any "active" class Add "active" class to selected tab
            $(".tab_content").hide(); //Hide all tab content
            .
            .
            .
        });
Joberror
  • 5,860
  • 3
  • 20
  • 15
0

I don't think you need to run the scripts again after the ajax, or at least that's not the "main" problem.

You seem to have some problems in the script smartColumn.js

Right now it seems to only operate on the ul with the id "column" ('#column'), and it is working on the one UL#column you do have, but of course your HTML has many other "columns" all of which have the class "column" ('.column') that you want it to work on as well.

Just to get the beginning of what you are trying to do, change all the selectors in smartColumn.js that say 'ul#column' to say 'ul.column' instead, and then alter the HTML so that the first "column" has a class="column" rather than an id="column".

That should solve the 100% wide columns at least.

That should solve your "Main" Problem. But there are other problems.

BigAB
  • 170
  • 5