精炼jquery插件的导航代码

时间:2016-12-11 02:50:43

标签: jquery jquery-plugins

我正在使用jquery插件并尝试在Next按钮上优化代码。插件的界面如下所示: enter image description here 最好的方法是先向我展示我的所有代码,然后我会提请你注意我的问题。

HTML:

<html>
<head>
<title>Carousel</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="button_carousel.css">
<script type="text/javascript" charset="utf-8" src="jquery.js"></script>
<script type="text/javascript" carset="utf-8" src="button_carousel.js"></script>

<script>
  $(document).ready(function() {
    //December has 31 days, therefore 31 buttons are required.
    var appointmentDays = [4,7,21];

    function myEventHandler(idvalue) {        
      if($.isFunction(idvalue))return;      
      console.debug("myEventHandler fired...id: " + idvalue);       
    }

    var bc = $('#carousel').button_carousel({
      days_in_month: 31,
      starting_day: 4,
      days_with_appointments: appointmentDays,
      eventHandler: myEventHandler
    });     
});
</script>
</head>
<body>
    <div id="carousel"></div>
</body>
</html>


CSS button_carousel.css:

/* Styling for prev button */
#nav_previous {
padding:0 0 0 0;    
position:absolute;
top:5px;
left:5px;
width:30px;
height: 30px;   
}

#slides {
overflow:hidden;
/* fix ie overflow issue */
position:absolute;
width:300px;
height:33px;
border:1px solid #ccc;
top:5px;
left:47px;
background-color: #F5F6CE;
}

/* remove the list styles, width : item width=85 * total items=31 */    
#slides ul {
position:relative;
left:0px;
top:0px;
list-style:none;
margin:0px;
padding:0px;    
width:2635px;           
}

#slides li {
width:85px;
height:30px;    
float:left;
}

/* Styling for next button */
#nav_next {
padding:0 0 0 0;    
position:absolute;
top:5px;
left:364px;
width:30px;
height: 30px;   
}

#nav_previous a {
display:block; 
width:31px; 
height:32px;
text-indent:-999em; 
outline:0;  
}

#nav_next a {
display:block; 
width:31px; 
height:32px;
text-indent:-999em; 
outline:0;  
}

a#prev {
background:url(images/left_black_arrow.png) no-repeat; 
}

a#prev:hover {
background:url(images/left_white_arrow.png) no-repeat;
}

a#next {
background:url(images/right_black_arrow.png) no-repeat; 
}

a#next:hover {
background:url(images/right_white_arrow.png) no-repeat;
}

input.btn {
 height:30px;
 width:65px;
 padding-right: 5px;
 padding-left: 5px;
 font-weight: bold;
 border:1px solid #000000;
}


JQUERY button_carousel.js:

(function ( $ ) {   

//grab the width and calculate left value
var item_width; 
var left_value;

//create the array of days
var day_names = new Array("SUN","MON","TUE","WED","THU","FRI","SAT");

var btnDefaultBackgroundColor = "#F0F0F0";

var buttonSelected = 0;

var buttonVisible = 0;  

$.fn.button_carousel = function(newoptions){
  console.debug("initializing button carousel");

  //Set all the properties of the parent div element,
  //no matter what its name
  $(this.selector).css({"background-color": "#D4D6D7",
    "width":"400px",
    "height":"45px",    
    "margin":"0 auto",
    "position":"relative",
    "border":"1px solid #ccc"               
  });     

  //Set the defaults
  var defaults = {
    days_in_month: 0,
    starting_day: 0,
    days_with_appointments: null,
    btnAppointmentFontColor: "#FF33EC",
    btnSelectedColor: "#9BE3F7",
    eventHandler: null      
  };          

  var options = $.extend({}, defaults, newoptions);

  //Bind the eventHandler function to receiving id values from button clicks.
  //See trigger below from all button clicks.
  $(options.eventHandler).bind("CarouselButtonID", function(event,data) {
         //console.debug("bind event id: " + data);
         options.eventHandler(data);
  });

  //Create initial carousel interface
  var container = $(this);
  container.append('<div id="nav_previous"><a id="prev" alt="previous button"></a></div><div id="slides"><ul></ul></div><div id="nav_next"><a id="next" alt="next button"></a></div>');

  //Set the display property for all div elements
   $(this.selector).each(function(){
       $("div").css("display", "inline-block");
   });

  //Use event delegation for the previous and next buttons
  $('div#nav_previous').on('click', 'a#prev', function(event) {
    event.preventDefault();
    //get the right position            
    var left_indent = parseInt($('#slides ul').css('left')) + item_width;
    console.debug("prev button - left_indent: " + left_indent + " item_width: " + item_width);
    //slide the item            
    $('#slides ul').animate({'left' : left_indent}, 200,function(){    

        //move the last item and put it as first item               
        $('#slides li:first').before($('#slides li:last'));           

        //set the default item to correct position
        $('#slides ul').css({'left' : left_value});

    });
    //buttonVisible--;  
    //console.debug("buttonVisible: " + buttonVisible);
    //cancel the link behavior            
    return false;
  });
  //Use event delegation for the previous and next buttons
  $('div#nav_next').on('click', 'a#next', function(event) {
    event.preventDefault();
    //get the right position
    //console.debug("next button - calc: " + parseInt($('#slides ul').css('left')));
    var left_indent = 0;
    var calc = parseInt($('#slides ul').css('left'));
    if(calc == 0)
        left_indent = 0;
    else
        left_indent = calc - item_width;
    console.debug("next button - left_indent: " + left_indent + " item_width: " + item_width + " left_value: " + left_value);
    //slide the item
    $('#slides ul').animate({'left' : left_indent}, 200, function () {

        //move the first item and put it as last item
        $('#slides li:last').after($('#slides li:first'));                  

        //set the default item to correct position
        $('#slides ul').css({'left' : left_value});

    });         
    //cancel the link behavior
    return false;
  });



  //populate unordered list with input type button elements.
  populate_carousel();

  item_width = $('#slides li').outerWidth(); 
  left_value = item_width * (-1);

  //Use event delegation on the slide buttons.
  $('div#slides ul').on('click', 'li input.btn', function(event) {
    var currentBtnID = $(this).attr('id');
    if(buttonSelected > 0)
    {           
        $( "li input.btn#" + buttonSelected ).css( "background-color", btnDefaultBackgroundColor );
        $(this).css("background-color", options.btnSelectedColor);
        buttonSelected = currentBtnID;          
    }
    else
    {
        $(this).css("background-color", options.btnSelectedColor);
        buttonSelected = currentBtnID;
    }
    $(options.eventHandler).trigger("CarouselButtonID", currentBtnID);      
  });     


  //Use this public function to reload all new options
  this.reloadAllOptions = function(newoptions){

    options = $.extend({}, defaults, newoptions); 
    var container = $('div#slides ul');
    //remove all the buttons
    container.each(function(){
        $( "li" ).remove();     
    });
    //populate unordered list with input type button elements.
    populate_carousel();

    var left_indent = parseInt($('#slides ul').css('left')) + item_width;

    //slide the item            
    $('#slides ul').animate({'left' : left_indent}, 200,function(){    

        //move the last item and put it as first item               
        $('#slides li:first').before($('#slides li:last'));           

        //set the default item to correct position
        $('#slides ul').css({'left' : left_value});

    });

    return this.each(function(){
       console.log(options);
    });
  }

  //Use this public function to update and highlight those days that have appointments associated.
  this.setButtonAppointmentFontColor = function(buttonColor){
      if(buttonColor == null)return $(this);
      var newoptions = {
        days_in_month: options.days_in_month,
        starting_day: options.starting_day,
        days_with_appointments: options.days_with_appointments,
        btnAppointmentFontColor: buttonColor,
        btnSelectedColor: options.btnSelectedColor,
        eventHandler: options.eventHandler          
      };
      options = $.extend({}, defaults, newoptions);
      HighlightDays(options.days_with_appointments);
      return this.each(function(){
       console.log(options);
      });
  }

  //Use this public function to update and highlight those days that have appointments associated.
  this.setButtonSelectedColor = function(buttonColor){
      if(buttonColor == null)return $(this);
      var newoptions = {
        days_in_month: options.days_in_month,
        starting_day: options.starting_day,
        days_with_appointments: options.days_with_appointments,
        btnAppointmentFontColor: options.btnAppointmentFontColor,
        btnSelectedColor: buttonColor,
        eventHandler: options.eventHandler          
      };
      options = $.extend({}, defaults, newoptions);
      return this.each(function(){
       console.log(options);
      });
  }

  //Use this public function to update and highlight those days that have appointments associated.
  this.setAppointmentDays = function(apptDaysArray){
      if(apptDaysArray == null)return $(this);
      var newoptions = {
        days_in_month: options.days_in_month,
        starting_day: options.starting_day,
        days_with_appointments: apptDaysArray,
        btnAppointmentFontColor: options.btnAppointmentFontColor,
        btnSelectedColor: options.btnSelectedColor,
        eventHandler: options.eventHandler          
      };
      options = $.extend({}, defaults, newoptions);
      HighlightDays(apptDaysArray);
      return this.each(function(){
       console.log(options);
      });
  }

  //Use this public function to update the days in the month only
  this.setDaysInMonth = function(days, startDay){
      if(days == null)return $(this);
      if(startDay == null)return $(this);
      var newoptions = {
        days_in_month: days,
        starting_day: startDay,
        days_with_appointments: null,
        btnAppointmentFontColor: options.btnAppointmentFontColor,
        btnSelectedColor: options.btnSelectedColor,
        eventHandler: options.eventHandler          
      };
      options = $.extend({}, defaults, newoptions);
      var container = $('div#slides ul');
      //remove all the buttons
      container.each(function(){
        $( "li" ).remove();     
      });
      //populate unordered list with input type button elements.
      populate_carousel();

      var left_indent = parseInt($('#slides ul').css('left')) + item_width;

      //slide the item            
      $('#slides ul').animate({'left' : left_indent}, 200,function(){    

        //move the last item and put it as first item               
        $('#slides li:first').before($('#slides li:last'));           

        //set the default item to correct position
        $('#slides ul').css({'left' : left_value});

      });

      return this.each(function(){
         console.log(options);
      });
  }

  this.setEventHandlerFunction = function(someFunction){
      if(someFunction == null)return $(this);
      var newoptions = {
        days_in_month: options.days_in_month,
        starting_day: options.starting_day,
        days_with_appointments: options.days_with_appointments,
        btnAppointmentFontColor: options.btnAppointmentFontColor,
        btnSelectedColor: options.btnSelectedColor,
        eventHandler: someFunction          
      };
      options = $.extend({}, defaults, newoptions);

      return this.each(function(){
       console.log(options);
      });
  }

  this.setSelected = function(id){
      if(buttonSelected > 0)
      {         
        $( "li input.btn#" + buttonSelected ).css( "background-color", btnDefaultBackgroundColor );
        $("li input.btn#" + id).css("background-color", options.btnSelectedColor);
        buttonSelected = id;            
      }
      else
      {
        $("li input.btn#" + id).css("background-color", options.btnSelectedColor);
        buttonSelected = id;
      }
      //move the desired day of the month to the left side of the carousel
      if(buttonSelected == 1)
          return this;

      for(var i = 2; i < options.days_in_month + 1; i++)
      {
        if(i == buttonSelected)
            break;
        //get the right position
        var left_indent = parseInt($('#slides ul').css('left')) - item_width;

        //slide the item
        $('#slides ul').animate({'left' : left_indent}, 0, function () {

            //move the first item and put it as last item
            $('#slides li:last').after($('#slides li:first'));                  

            //set the default item to correct position
            $('#slides ul').css({'left' : left_value});

        });
      }
      return this;
  }

  this.triggerButtonClicked = function(id){
      $(options.eventHandler).trigger("CarouselButtonID", id);
      return this;
  }

  this.isAppointmentDay = function(id){
      if(options.days_with_appointments == null) return false;
      var appday = false;
      var day = 0;
      for(var i = 0; i < options.days_with_appointments.length; i++)
      {
          day = options.days_with_appointments[i];
          if(day == id)
          {
            appday = true;
            break;
          }
      }
      return appday;
  }

  function populate_carousel() {
    var index = options.starting_day;
    var container = $('div#slides ul');

    for(var i = 1; i < options.days_in_month + 1; i++)
    {
        container.append('<li><input type="button" id="' + i + '" class="btn" value="' + day_names[index] + " " + i + '"></li>');
        if(index < 6)
           index++;
        else
           index = 0; //reset           
    }       

    HighlightDays(options.days_with_appointments);
  }

  function HighlightDays(appointmentsArray)
  {
    if(appointmentsArray == null)return;
    //console.debug("HighlightDays(): " + appointmentsArray);
    resetButtonFontColor()
    var identifier;
    var match = false;
    $('li input.btn').each(function(){
        identifier = this.id;
        //console.debug("id: " + identifier);
        match = haveMatch(identifier, appointmentsArray);
        if(match == true)
        {
            $(this).css("color", options.btnAppointmentFontColor);
        }
    });

  }

  function haveMatch(number, appointmentsArray){
    var match = false;
    for(var i = 0; i < appointmentsArray.length; i++)
    {
        if(number == appointmentsArray[i])
        {
            match = true;
            break;
        }
    }
    return match;
  }

  function resetButtonFontColor()
  {
    $('li input.btn').each(function(){
      $(this).css("color", '#000000');  //black 
    });
  }

  return this.each(function(){
     console.log(options);
  });     
};  

}( jQuery ));

好的...所以,如果你加载了所有代码,然后点击下一步按钮(指向右箭头按钮 - >),你会注意到一个异常的方式DAY按钮前进。按钮应该一次只前进一个按钮,但是,当您第一次按下NEXT按钮时,2个DAY按钮前进。这不应该发生。如果继续按下NEXT按钮,则DAY按钮此后一次前进一个。问题代码是:

$('div#nav_next').on('click', 'a#next', function(event) {
    event.preventDefault();
    //get the right position
    //console.debug("next button - calc: " + parseInt($('#slides ul').css('left')));
    var left_indent = 0;
    var calc = parseInt($('#slides ul').css('left'));
    if(calc == 0)
        left_indent = 0;
    else
        left_indent = calc - item_width;
    console.debug("next button - left_indent: " + left_indent + " item_width: " + item_width + " left_value: " + left_value);
    //slide the item
    $('#slides ul').animate({'left' : left_indent}, 200, function () {

        //move the first item and put it as last item
        $('#slides li:last').after($('#slides li:first'));                  

        //set the default item to correct position
        $('#slides ul').css({'left' : left_value});

    });
    //cancel the link behavior
    return false;
  });

箭头按钮只是指向css中定义的箭头图像的锚标签,您可能需要使用它来获取可点击的内容。

我已经玩了好几个小时了,并且无法弄清楚为什么按钮会在第一次点击时前进两个DAY按钮。我需要另外一双眼睛来解决这个问题,因为我的眼睛已经上釉。请指教。

1 个答案:

答案 0 :(得分:1)

我对您的代码进行了一些更改:

 //Use event delegation for the previous and next buttons
    $('div#nav_next').on('click', 'a#next', function(event) {
      event.preventDefault();
      //get the right position
      //console.debug("next button - calc: " + parseInt($('#slides ul').css('left')));
      var left_indent = 0;
      var calc = parseInt($('#slides ul').css('left'));
      console.log(calc);
      //  if (calc == 0)
      //    left_indent = 0;
      //  else
      //  left_indent = calc - item_width;
      console.debug("next button - left_indent: " + left_indent + " item_width: " + item_width + " left_value: " + left_value);
      //slide the item
      $('#slides ul').animate({
        'left': '-' + item_width
      }, 200, function() {

        //move the first item and put it as last item
        $('#slides li:last').after($('#slides li:first'));

        //set the default item to correct position
        $('#slides ul').css({
          'left': 0
        });

      });
      //cancel the link behavior
      return false;
    });

动画完成后,设置&#34;左&#34; value到item_width(-85px)也将元素移动到其父元素的末尾。这导致-85px左边距没有元素填充它(我们移动到元素的末尾)因此第二个元素将填充该空间。

另外,一个工作的JSFiddle(减去图像):https://jsfiddle.net/0x402dte/