js实现通过矩形框的八个锚点,对其进行缩放。问题是,chrome下测试成功,但ie8下每次点击锚点准备放缩时,矩形框都会先下移一步。怎么回事呢,和ie8下的事件监听等方法有关吗!??
求大神指导。

解决方案 »

  1.   

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <title>拖拉缩放效果</title>
    </head>
    <body>
    <script>
    var isIE = (document.all) ? true : false;
    var $ = function (id) {
     return "string" == typeof id ? document.getElementById(id) : id;
    };
    var Class = {
     create: function() {
      return function() { this.initialize.apply(this, arguments); }
     }
    }
    var Extend = function(destination, source) {
     for (var property in source) {
      destination[property] = source[property];
     }
    }
    var Bind = function(object, fun) {
     return function() {
      return fun.apply(object, arguments);
     }
    }
    var BindAsEventListener = function(object, fun) {
     var args = Array.prototype.slice.call(arguments).slice(2);
     return function(event) {
      return fun.apply(object, [event || window.event].concat(args));
     }
    }
    var CurrentStyle = function(element){
     return element.currentStyle || document.defaultView.getComputedStyle(element, null);
    }
    function addEventHandler(oTarget, sEventType, fnHandler) {
     if (oTarget.addEventListener) {
      oTarget.addEventListener(sEventType, fnHandler, false);
     } else if (oTarget.attachEvent) {
      oTarget.attachEvent("on" + sEventType, fnHandler);
     } else {
      oTarget["on" + sEventType] = fnHandler;
     }
    };
    function removeEventHandler(oTarget, sEventType, fnHandler) {
        if (oTarget.removeEventListener) {
            oTarget.removeEventListener(sEventType, fnHandler, false);
        } else if (oTarget.detachEvent) {
            oTarget.detachEvent("on" + sEventType, fnHandler);
        } else { 
            oTarget["on" + sEventType] = null;
        }
    };
    //缩放程序
    var Resize = Class.create();
    Resize.prototype = {
      //缩放对象
      initialize: function(obj, options) {
     this._obj = $(obj);//缩放对象
     
     this._styleWidth = this._styleHeight = this._styleLeft = this._styleTop = 0;//样式参数
     this._sideRight = this._sideDown = this._sideLeft = this._sideUp = 0;//坐标参数
     this._fixLeft = this._fixTop = 0;//定位参数
     this._scaleLeft = this._scaleTop = 0;//定位坐标
     
     this._mxSet = function(){};//范围设置程序
     this._mxRightWidth = this._mxDownHeight = this._mxUpHeight = this._mxLeftWidth = 0;//范围参数
     this._mxScaleWidth = this._mxScaleHeight = 0;//比例范围参数
     
     this._fun = function(){};//缩放执行程序
     
     //获取边框宽度
     var _style = CurrentStyle(this._obj);
     this._borderX = (parseInt(_style.borderLeftWidth) || 0) + (parseInt(_style.borderRightWidth) || 0);
     this._borderY = (parseInt(_style.borderTopWidth) || 0) + (parseInt(_style.borderBottomWidth) || 0);
     //事件对象(用于绑定移除事件)
     this._fR = BindAsEventListener(this, this.Resize);
     this._fS = Bind(this, this.Stop);
     this._touch = null;//当前触发对象
     
     this.SetOptions(options);
     //范围限制
     this.Max = !!this.options.Max;
     this._mxContainer = $(this.options.mxContainer) || null;
     this.mxLeft = Math.round(this.options.mxLeft);
     this.mxRight = Math.round(this.options.mxRight);
     this.mxTop = Math.round(this.options.mxTop);
     this.mxBottom = Math.round(this.options.mxBottom);
     //宽高限制
     this.Min = !!this.options.Min;
     this.minWidth = Math.round(this.options.minWidth);
     this.minHeight = Math.round(this.options.minHeight);
     //按比例缩放
     this.Scale = !!this.options.Scale;
     this.Ratio = Math.max(this.options.Ratio, 0);
     
     this.onResize = this.options.onResize;
     
     this._obj.style.position = "absolute";
     !this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || (this._mxContainer.style.position = "relative");
      addEventHandler(this.Resize, "mousedown", function(e){ this.Start(window.event || e)});
      },
      //设置默认属性
      SetOptions: function(options) {
        this.options = {//默认值
      Max:  false,//是否设置范围限制(为true时下面mx参数有用)
      mxContainer:"",//指定限制在容器内
      mxLeft:  0,//左边限制
      mxRight: 9999,//右边限制
      mxTop:  0,//上边限制
      mxBottom: 9999,//下边限制
      Min:  false,//是否最小宽高限制(为true时下面min参数有用)
      minWidth: 50,//最小宽度
      minHeight: 50,//最小高度
      Scale:  false,//是否按比例缩放
      Ratio:  0,//缩放比例(宽/高)
      onResize: function(){}//缩放时执行
        };
        Extend(this.options, options || {});
      },
      //设置触发对象
      Set: function(resize, side) {
     var resize = $(resize), fun;
     if(!resize) return;
     //根据方向设置
     switch (side.toLowerCase()) {
     case "up" :
      fun = this.Up;
      break;
     case "down" :
      fun = this.Down;
      break;
     case "left" :
      fun = this.Left;
      break;
     case "right" :
      fun = this.Right;
      break;
     case "left-up" :
      fun = this.LeftUp;
      break;
     case "right-up" :
      fun = this.RightUp;
      break;
     case "left-down" :
      fun = this.LeftDown;
      break;
     case "right-down" :
     default :
      fun = this.RightDown;
     };
     //设置触发对象
     //addEventHandler(resize, "mousedown", function(e){ this._fun = fun; this._touch = resize; this.Start(window.event || e); });
     addEventHandler(resize, "mousedown", BindAsEventListener(this, this.Start, fun));
      },
      //准备缩放
      Start: function(e, fun, _touch) { 
     //防止冒泡(跟拖放配合时设置)
     if(isIE){ e.cancelBubble = true; } else { e.stopPropagation(); }
     //设置执行程序
     this._fun = fun;
     //样式参数值
     this._styleWidth = this._obj.clientWidth;
     this._styleHeight = this._obj.clientHeight;
     this._styleLeft = this._obj.offsetLeft;
     this._styleTop = this._obj.offsetTop;
     //四条边定位坐标
     this._sideLeft = e.clientX - this._styleWidth;
     this._sideRight = e.clientX + this._styleWidth;
     this._sideUp = e.clientY - this._styleHeight;
     this._sideDown = e.clientY + this._styleHeight;
     //top和left定位参数
     this._fixLeft = this._styleLeft + this._styleWidth;
     this._fixTop = this._styleTop + this._styleHeight;
     //缩放比例
     if(this.Scale){
      //设置比例
      this.Ratio = Math.max(this.Ratio, 0) || this._styleWidth / this._styleHeight;
      //left和top的定位坐标
      this._scaleLeft = this._styleLeft + this._styleWidth / 2;
      this._scaleTop = this._styleTop + this._styleHeight / 2;
     };
     //范围限制
     if(this.Max){
      //设置范围参数
      var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom;
      //如果设置了容器,再修正范围参数
      if(!!this._mxContainer){
       mxLeft = Math.max(mxLeft, 0);
       mxTop = Math.max(mxTop, 0);
       mxRight = Math.min(mxRight, this._mxContainer.clientWidth);
       mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);
      };
      //根据最小值再修正
      mxRight = Math.max(mxRight, mxLeft + (this.Min ? this.minWidth : 0) + this._borderX);
      mxBottom = Math.max(mxBottom, mxTop + (this.Min ? this.minHeight : 0) + this._borderY);
      //由于转向时要重新设置所以写成function形式
      this._mxSet = function(){
       this._mxRightWidth = mxRight - this._styleLeft - this._borderX;
       this._mxDownHeight = mxBottom - this._styleTop - this._borderY;
       this._mxUpHeight = Math.max(this._fixTop - mxTop, this.Min ? this.minHeight : 0);
       this._mxLeftWidth = Math.max(this._fixLeft - mxLeft, this.Min ? this.minWidth : 0);
      };
      this._mxSet();
      //有缩放比例下的范围限制
      if(this.Scale){
       this._mxScaleWidth = Math.min(this._scaleLeft - mxLeft, mxRight - this._scaleLeft - this._borderX) * 2;
       this._mxScaleHeight = Math.min(this._scaleTop - mxTop, mxBottom - this._scaleTop - this._borderY) * 2;
      };
     };
     //mousemove时缩放 mouseup时停止
     addEventHandler(document, "mousemove", this._fR);
     addEventHandler(document, "mouseup", this._fS);
     if(isIE){
      addEventHandler(this._obj, "losecapture", this._fS);
      this._obj.setCapture();
     }else{
      addEventHandler(window, "blur", this._fS);
      e.preventDefault();
     };
      },
      //缩放
      Resize: function(e) {
     //清除选择
     window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
     //执行缩放程序
     this._fun(e);
     //设置样式,变量必须大于等于0否则ie出错
     with(this._obj.style){
      width = this._styleWidth + "px"; height = this._styleHeight + "px";
      top = this._styleTop + "px"; left = this._styleLeft + "px";
     }
     //附加程序
     this.onResize();
      },
      //缩放程序
      //上
      Up: function(e) {
     this.RepairY(this._sideDown - e.clientY, this._mxUpHeight);
     this.RepairTop();
     this.TurnDown(this.Down);
      },
      //下
      Down: function(e) {
     this.RepairY(e.clientY - this._sideUp, this._mxDownHeight);
     this.TurnUp(this.Up);
      },
      //右
      Right: function(e) {
     this.RepairX(e.clientX - this._sideLeft, this._mxRightWidth);
     this.TurnLeft(this.Left);
      },
      //左
      Left: function(e) {
     this.RepairX(this._sideRight - e.clientX, this._mxLeftWidth);
     this.RepairLeft();
     this.TurnRight(this.Right);
      },
      //右下
      RightDown: function(e) {
     this.RepairAngle(
      e.clientX - this._sideLeft, this._mxRightWidth,
      e.clientY - this._sideUp, this._mxDownHeight
     );
     this.TurnLeft(this.LeftDown) || this.TurnUp(this.RightUp);
      },
      //右上
      RightUp: function(e) {
     this.RepairAngle(
      e.clientX - this._sideLeft, this._mxRightWidth,
      this._sideDown - e.clientY, this._mxUpHeight
     );
     this.RepairTop();
     this.TurnLeft(this.LeftUp) || this.TurnDown(this.RightDown);
      },
      //左下
      LeftDown: function(e) {
     this.RepairAngle(
      this._sideRight - e.clientX, this._mxLeftWidth,
      e.clientY - this._sideUp, this._mxDownHeight
     );
     this.RepairLeft();
     this.TurnRight(this.RightDown) || this.TurnUp(this.LeftUp);
      },
      //左上
      LeftUp: function(e) {
     this.RepairAngle(
      this._sideRight - e.clientX, this._mxLeftWidth,
      this._sideDown - e.clientY, this._mxUpHeight
     );
     this.RepairTop(); this.RepairLeft();
     this.TurnRight(this.RightUp) || this.TurnDown(this.LeftDown);
      },
      

  2.   

     //修正程序
      //水平方向
      RepairX: function(iWidth, mxWidth) {
     iWidth = this.RepairWidth(iWidth, mxWidth);
     if(this.Scale){
      var iHeight = Math.round(iWidth / this.Ratio);
      if(this.Max && iHeight > this._mxScaleHeight){
       iWidth = Math.round((iHeight = this._mxScaleHeight) * this.Ratio);
      }else if(this.Min && iHeight < this.minHeight){
       var tWidth = Math.round(this.minHeight * this.Ratio);
       if(tWidth < mxWidth){ iHeight = this.minHeight; iWidth = tWidth; }
      }
      this._styleHeight = iHeight;
      this._styleTop = this._scaleTop - iHeight / 2;
     }
     this._styleWidth = iWidth;
      },
      //垂直方向
      RepairY: function(iHeight, mxHeight) {
     iHeight = this.RepairHeight(iHeight, mxHeight);
     if(this.Scale){
      var iWidth = Math.round(iHeight * this.Ratio);
      if(this.Max && iWidth > this._mxScaleWidth){
       iHeight = Math.round((iWidth = this._mxScaleWidth) / this.Ratio);
      }else if(this.Min && iWidth < this.minWidth){
       var tHeight = Math.round(this.minWidth / this.Ratio);
       if(tHeight < mxHeight){ iWidth = this.minWidth; iHeight = tHeight; }
      }
      this._styleWidth = iWidth;
      this._styleLeft = this._scaleLeft - iWidth / 2;
     }
     this._styleHeight = iHeight;
      },
      //对角方向
      RepairAngle: function(iWidth, mxWidth, iHeight, mxHeight) {
     iWidth = this.RepairWidth(iWidth, mxWidth); 
     if(this.Scale){
      iHeight = Math.round(iWidth / this.Ratio);
      if(this.Max && iHeight > mxHeight){
       iWidth = Math.round((iHeight = mxHeight) * this.Ratio);
      }else if(this.Min && iHeight < this.minHeight){
       var tWidth = Math.round(this.minHeight * this.Ratio);
       if(tWidth < mxWidth){ iHeight = this.minHeight; iWidth = tWidth; }
      }
     }else{
      iHeight = this.RepairHeight(iHeight, mxHeight);
     }
     this._styleWidth = iWidth;
     this._styleHeight = iHeight;
      },
      //top
      RepairTop: function() {
     this._styleTop = this._fixTop - this._styleHeight;
      },
      //left
      RepairLeft: function() {
     this._styleLeft = this._fixLeft - this._styleWidth;
      },
      //height
      RepairHeight: function(iHeight, mxHeight) {
     iHeight = Math.min(this.Max ? mxHeight : iHeight, iHeight);
     iHeight = Math.max(this.Min ? this.minHeight : iHeight, iHeight, 0);
     return iHeight;
      },
      //width
      RepairWidth: function(iWidth, mxWidth) {
     iWidth = Math.min(this.Max ? mxWidth : iWidth, iWidth);
     iWidth = Math.max(this.Min ? this.minWidth : iWidth, iWidth, 0);
     return iWidth;
      },
      //转向程序
      //转右
      TurnRight: function(fun) {
     if(!(this.Min || this._styleWidth)){
      this._fun = fun;
      this._sideLeft = this._sideRight;
      this.Max && this._mxSet();
      return true;
     }
      },
      //转左
      TurnLeft: function(fun) {
     if(!(this.Min || this._styleWidth)){
      this._fun = fun;
      this._sideRight = this._sideLeft;
      this._fixLeft = this._styleLeft;
      this.Max && this._mxSet();
      return true;
     }
      },
      //转上
      TurnUp: function(fun) {
     if(!(this.Min || this._styleHeight)){
      this._fun = fun;
      this._sideDown = this._sideUp;
      this._fixTop = this._styleTop;
      this.Max && this._mxSet();
      return true;
     }
      },
      //转下
      TurnDown: function(fun) {
     if(!(this.Min || this._styleHeight)){
      this._fun = fun;
      this._sideUp = this._sideDown;
      this.Max && this._mxSet();
      return true;
     }
      },
      //停止缩放
      Stop: function() {
     removeEventHandler(document, "mousemove", this._fR);
     removeEventHandler(document, "mouseup", this._fS);
     if(isIE){
      removeEventHandler(this._obj, "losecapture", this._fS);
      this._obj.releaseCapture();
     }else{
      removeEventHandler(window, "blur", this._fS);
     }
      }
    };
    </script>
    <style type="text/css">
    #rRightDown,#rLeftDown,#rLeftUp,#rRightUp,#rRight,#rLeft,#rUp,#rDown{
     position:absolute;
     background:#C00;
     width:7px;
     height:7px;
     z-index:5;
     font-size:0;
    }
    #rLeftDown,#rRightUp{cursor:ne-resize;}
    #rRightDown,#rLeftUp{cursor:nw-resize;}
    #rRight,#rLeft{cursor:e-resize;}
    #rUp,#rDown{cursor:n-resize;}
    #rLeftDown{left:-4px;bottom:-4px;}
    #rRightUp{right:-4px;top:-4px;}
    #rRightDown{right:-4px;bottom:-4px;background-color:#00F;}
    #rLeftUp{left:-4px;top:-4px;}
    #rRight{right:-4px;top:50%;margin-top:-4px;}
    #rLeft{left:-4px;top:50%;margin-top:-4px;}
    #rUp{top:-4px;left:50%;margin-left:-4px;}
    #rDown{bottom:-4px;left:50%;margin-left:-4px;}
    #bgDiv{width:600px; height:300px; border:10px solid #666666; position:relative;}
    #dragDiv{border:1px solid #000000; width:100px; height:60px; top:50px; left:50px; background:#fff;}
    </style>
    <div id="bgDiv">
      <div id="dragDiv">
        <div id="rRightDown"> </div>
        <div id="rLeftDown"> </div>
        <div id="rRightUp"> </div>
        <div id="rLeftUp"> </div>
        <div id="rRight"> </div>
        <div id="rLeft"> </div>
        <div id="rUp"> </div>
        <div id="rDown"></div>
      </div>
    </div>
    <div>
    <input id="idScale" type="button" value="设置比例" />
    <input id="idMin" type="button" value="设置最小范围" />
    </div>
    <script>
    var rs = new Resize("dragDiv", { Max: true, mxContainer: "bgDiv" });
    rs.Set("rRightDown", "right-down");
    rs.Set("rLeftDown", "left-down");
    rs.Set("rRightUp", "right-up");
    rs.Set("rLeftUp", "left-up");
    rs.Set("rRight", "right");
    rs.Set("rLeft", "left");
    rs.Set("rUp", "up");
    rs.Set("rDown", "down");
    $("idScale").onclick = function(){
     if(rs.Scale){
      this.value = "设置比例";
      rs.Scale = false;
     }else{
      this.value = "取消比例";
      rs.Scale = true;
     }
    }
    $("idMin").onclick = function(){
     if(rs.Min){
      this.value = "设置最小范围";
      rs.Min = false;
     }else{
      this.value = "取消最小范围";
      rs.Min = true;
     }
    }
    new Resize("dragDiv", { Limit: true, mxContainer: "bgDiv" });
    </script>
    </body>
    </html>