Javascript/css in IE8

2019-02-27 02:43发布

问题:

Issue I am having is rotating an image (clock hands to be precise) in IE. The script below works to an extent (there is actually animation going on) but it's rotating completely off axis.

I am by no means a wiz with Javascript/Jquery and am a bit lost when it comes to working out how to do this properly in IE8.

Code below:

(function(jQuery)
{
  jQuery.fn.clock = function(options)
  {
    var defaults = {
      offset: '+0',
      type: 'analog'
    };
    var _this = this;
    var opts = jQuery.extend(defaults, options);

    setInterval( function() {
      var seconds = jQuery.calcTime(opts.offset).getSeconds();
      if(opts.type=='analog')
      {
        var sdegree = seconds * 6;
        var srotate = "rotate(" + sdegree + "deg)";
        var rad = Math.PI/180 * sdegree,
            cos = Math.cos(rad),
            sin = Math.sin(rad);
        jQuery(_this).find(".sec").css({"-moz-transform" : srotate, "-webkit-transform" : srotate, "-ms-transform" : srotate,
                                        'filter': "progid:DXImageTransform.Microsoft.Matrix(M11="+cos+", M12="+(-sin)+", M21="+sin+", M22="+cos+", SizingMethod='auto expand')"});
      }
      else
      {
        jQuery(_this).find(".sec").html(seconds);
      }
    }, 1000 );

    setInterval( function() {
      var hours = jQuery.calcTime(opts.offset).getHours();
      var mins = jQuery.calcTime(opts.offset).getMinutes();
      if(opts.type=='analog')
      {
        var hdegree = hours * 30 + (mins / 2);
        var hrotate = "rotate(" + hdegree + "deg)";
        var rad = Math.PI/180 * hdegree,
            cos = Math.cos(rad),
            sin = Math.sin(rad);
        jQuery(_this).find(".hour").css({"-moz-transform" : hrotate, "-webkit-transform" : hrotate, "-ms-transform" : hrotate,
                                         'filter': "progid:DXImageTransform.Microsoft.Matrix(M11="+cos+", M12="+(-sin)+", M21="+sin+", M22="+cos+", SizingMethod='auto expand')"});
      }
      else
      {
        jQuery(_this).find(".hour").html(hours+':');
      }
      var meridiem = hours<12?'AM':'PM';
      jQuery(_this).find('.meridiem').html(meridiem);
    }, 1000 );

    setInterval( function() {
      var mins = jQuery.calcTime(opts.offset).getMinutes();
      if(opts.type=='analog')
      {
        var mdegree = mins * 6;
        var mrotate = "rotate(" + mdegree + "deg)";
        var rad = Math.PI/180 * mdegree,
            cos = Math.cos(rad),
            sin = Math.sin(rad);
        jQuery(_this).find(".min").css({"-moz-transform" : mrotate, "-webkit-transform" : mrotate, "-ms-transform" : mrotate,
                                        'filter': "progid:DXImageTransform.Microsoft.Matrix(M11="+cos+", M12="+(-sin)+", M21="+sin+", M22="+cos+", SizingMethod='auto expand')"});                
      }
      else
      {
        jQuery(_this).find(".min").html(mins+':');
      }
    }, 1000 );
  }
})(jQuery);


jQuery.calcTime = function(offset) {
  d = new Date();
  utc = d.getTime() + (d.getTimezoneOffset() * 60000);
  nd = new Date(utc + (3600000*offset));
  return nd;
};

回答1:

Check this example: This is working on IE...

createLine: function(x1, y1, x2, y2, options){

              // Check if browser is Internet Exploder ;)
              var isIE = navigator.userAgent.indexOf("MSIE") > -1;
              if (x2 < x1){
                var temp = x1;
                x1 = x2;
                x2 = temp;
                temp = y1;
                y1 = y2;
                y2 = temp;
              }
              var line = document.createElement("div");
              line.className = "global_dashboard_line";

              // Formula for the distance between two points
              // http://www.mathopenref.com/coorddist.html
              var length = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));

              line.style.width = length + "px";
              line.style.borderColor = options.color;
              line.style.zIndex = options.zindex;
              line.style.borderWidth = options.stroke + " 0px 0px 0px";

              if(isIE){
                line.style.top = (y2 > y1) ? y1 + "px" : y2 + "px";
                line.style.left = x1 + "px";
                var nCos = (x2-x1)/length;
                var nSin = (y2-y1)/length;
                line.style.filter = "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=" + nCos + ", M12=" + -1*nSin + ", M21=" + nSin + ", M22=" + nCos + ")";
              }else{
                var angle = Math.atan((y2-y1)/(x2-x1));
                line.style.top = y1 + 0.5*length*Math.sin(angle) + "px";
                line.style.left = x1 - 0.5*length*(1 - Math.cos(angle)) + "px";
                line.style.MozTransform = line.style.WebkitTransform = line.style.OTransform= "rotate(" + angle + "rad)";
              }
              return line;
            }
    }

This is a function of a plugin that i made for drawing lines in an html element... It uses rotations for oblique lines. if you want to check the entire plugin go to: https://github.com/tbem/jquery.line



回答2:

This should work across all browsers, including IE8: http://jsfiddle.net/SrSus/26/show/

HTML

<ul id="analog-clock" class="analog">
    <li class="hour"></li>
    <li class="min"></li>
    <li class="sec"></li>
    <li class="meridiem"></li>
</ul>

Javascript

(function ($) {
    $.fn.clock = function (options) {
        var self = this,
            el,
            msie8 = (/(msie) ([\w.]+)/i).test(navigator.userAgent),
            defaults = {
                offset: "+0"
            },
            opts = $.extend(defaults, options),
            calcTime = function (offset) {
                var d = new Date(),
                    utc = d.getTime() + (d.getTimezoneOffset() * 60000),
                    nd = new Date(utc + (3600000 * offset));
                return nd;
            },
            rotate = function (o, degree) {
                var rotate = "rotate(" + degree + "deg)",
                    rad, cos, sin, w, h;

                if (o.cur === degree) {
                    return;
                }
                o.cur = degree;

                if (msie8) {
                    rad = (degree * Math.PI) / 180;
                    cos = Math.cos(rad);
                    sin = Math.sin(rad);

                    o.el.css({
                        'filter': 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod="auto expand", M11 = ' + cos + ', M12 = ' + (-sin) + ', M21 = ' + sin + ', M22 = ' + cos + ')'
                    });

                    w = o.el.width(); // obtain element sizes again
                    h = o.el.height();
                    o.el.css({
                        "marginLeft": -Math.round((w - o.w) / 2),
                        "marginTop": -Math.round((h - o.h) / 2)
                    });
                }
                else {
                    o.el.css({
                        "-moz-transform": rotate,
                        "-webkit-transform": rotate,
                        "-ms-transform": rotate,
                        "-sand-transform": rotate
                    });
                }
            };


        // store elements and sizes
        el = $(self).children(".sec");
        opts.sec = { el: el, w: el.width(), h: el.height(), cur: null };
        el = $(self).children(".hour");
        opts.hour = { el: el, w: el.width(), h: el.height(), cur: null };
        el = $(self).children(".min");
        opts.min = { el: el, w: el.width(), h: el.height(), cur: null };

        setInterval(function () {
            var time = calcTime(opts.offset),
                hours = time.getHours(),
                mins = time.getMinutes(),
                seconds = time.getSeconds(),
                degree;

            // hours
            degree = hours * 30 + (mins / 2);
            rotate(opts.hour, degree);

            // minutes
            degree = mins * 6;
            rotate(opts.min, degree);

            // seconds
            degree = seconds * 6;
            rotate(opts.sec, degree);
        }, 1000);
    };
})($);


$("#analog-clock").clock();