>웹 프론트엔드 >JS 튜토리얼 >자체 모듈 인스턴스 캡슐화에 대한 자세한 설명

자체 모듈 인스턴스 캡슐화에 대한 자세한 설명

小云云
小云云원래의
2018-01-30 17:16:081492검색

드래그 앤 드롭 모듈을 캡슐화해 보세요. 이 과정에서 우여곡절을 겪었습니다. 처음에는 style.left만 사용하려고 했으나, position:absolute 설정이 필요합니다. 코드에 약간의 영향을 미칠 수 있습니다. CSS 변환이 호환성에 영향을 주지만 여기서는 여전히 이 속성의 변환을 사용하여 이동을 완료합니다.

스타일만으로 완성된 코드

말할 것도 없이 바로 코드로 넘어가겠습니다:

html과 css 위치는 여기서 설정해야 합니다. 그래서 이 코드를 처음 작성할 때 잊어버렸습니다. , JS를 제대로 작성했는데도 효과가 전혀 나오지 않네요....정말 쇼트입니다

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>学习</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #box{
            width: 200px;
            height: 200px;
            background: #6f6;
            font-size: 20px;
            cursor:move;
            position: absolute;
        }
    </style>

</head>
<body>
  <p id="box"></p>
  <script src="js/drag_module.js"></script>
</body>
</html>

포인트! ! JS

;    //这个分号是为了防止其他的模块最后忘记加分号,导致错误。
(function() {
  
  //构造函数,属于每一个实例
  function Drag(selector) {
    this.elem = typeof selector == 'object' ? selector : document.getElementById(selector);
    //鼠标初始位置
    this.startX = 0;
    this.startY = 0;
    //元素初始位置
    this.sourceX = 0;
    this.sourceY = 0;

    this.init();
  }

  //原型,共有的
  Drag.prototype = {
    constructor: Drag,
    init: function() {
      this.setDrag();
    },

    //用于获取元素当前的位置信息
    getPosition: function() {
      var that = this;
      var pos = {};
      pos = {
        x: that.elem.offsetLeft,
        y: that.elem.offsetTop
      };
      return pos;
    },
    //用来设置当前元素的位置
    setPosition: function(pos) {
      this.elem.style.left = pos.x + 'px';
      this.elem.style.top = pos.y + 'px';
    },

    //该方法用来绑定事件
    setDrag: function() {
      var self = this;
      this.elem.addEventListener('mousedown', start, false);

      function start(event) {

        self.startX = event.pageX;
        self.startY = event.pageY;

        var pos = self.getPosition();

        self.sourceX = pos.x;
        self.sourceY = pos.y;

        document.addEventListener('mousemove', move, false);
        document.addEventListener('mouseup', end, false);
      }

      function move(event) {
        //总体思想:鼠标距浏览器距-鼠标距元素距离
        var currentX = event.pageX; //当前的鼠标x位置
        var currentY = event.pageY; //当前的鼠标y位置

        var distanceX = currentX - self.startX; //鼠标移动的距离x
        var distanceY = currentY - self.startY; //鼠标移动的距离y

        self.setPosition({
          x: self.sourceX + distanceX,
          y: self.sourceY + distanceY
        });

      }

      function end(event) {
        document.removeEventListener('mousemove', move);
        document.removeEventListener('mouseup', end);
      }
    }
  };
  
  //暴露在外
  window.Drag = Drag;
})();


new Drag('box');

이 코드는 비교적 이해하기 쉽습니다. Bo Dashen의 코드를 처음 봤을 때 정규 표현식이 왜 사용되는지 예상하지 못했기 때문에 실제로 번역의 사용을 이해하지 못했습니다...

그래도 상대적으로 간단하지만 이 코드의 원리를 분석해야 합니다.

1. 생성자에는 Drag()라는 생성자가 있습니다. 생성자에서 우리가 설정한 메서드와 속성은 다음과 같이 고유합니다. 위치 정보 등 프로토타입에는 요소 위치 정보를 얻기 위한 getPosition(), 요소 위치 설정을 위한 setPosition(), 이벤트 바인딩을 위한 setDrag() 세 가지 메소드가 있습니다. 이 세 가지는 공개이므로 리소스를 절약하기 위해 이를 원기.

2. 이 코드의 실행 원리는 다음과 같습니다. 마우스를 누르면 sourceX/Y 요소의 초기 위치 정보와 마우스 이동이 완료되면 startX/Y의 초기 위치 정보가 획득됩니다. 두 마우스 위치를 빼면 마우스가 이동하는 거리X/Y를 얻을 수 있습니다. 이는 요소가 이동하는 거리이기도 합니다. 그런 다음 이 값을 요소의 style.left/top에 할당합니다. 요소 드래그가 이루어집니다.

Transform과 스타일의 결합

기술의 발전으로 인해 점점 더 많은 장치가 CSS3를 지원하기 시작했습니다. 또한 스타일은 더 많은 리소스를 차지하고 효율성에 문제가 있으므로 변환 사용을 고려합니다.

브라우저 호환 쓰기 방법

먼저 Drag() 함수 앞에 개인 속성을 추가합니다.

var transform = getTransform();

아래에 개인 메서드 추가:

function getTransform() {
    var transform = "",
      pStyle = document.createElement('p').style,
      transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'oTransform'],
      i = 0,
      l = transformArr.length;

    for (; i < l; i++) {
      if (transformArr[i] in pStyle) {
        return transform = transformArr[i];
      }
    }
    return transform;
  }

PS: 다음에 탐색을 판단하려면 createElement() 메서드를 기억하세요. 장치가 호환됩니다!

또한 동일한 형식으로 getPosition() 아래에 함수를 추가해야 합니다.

getTranslate: function() {
      var val = {};
      var transformValue = document.defaultView.getComputedStyle(this.elem, false)[transform];
      if(transformValue=='none'){
        val={x:0,y:0};
      }else{
        var transformArr = transformValue.match(/-?\d+/g);
        val = {
          x: Number(transformArr[4]),
          y: Number(transformArr[5])
        };
      }


      return val;
    },

PS: 변환 값이 없음인지 확인해야 하는 이유는 초기화 상태에서 요소가 변환 속성을 설정하지 않았기 때문입니다. 그래서 [4][5]는 정규화 후에 배열에서 찾을 수 없기 때문에 val의 두 속성을 0으로 설정합니다. 이 값은 나중에 변환될 번역X와 번역Y의 값입니다.

계속 코드를 작성하세요. 위 단락에서는 번역의 X 및 Y 값을 추출하는 데 사용했습니다. 다음 단락을 보세요:

getPosition: function() {
      var that = this;
      var pos = {};
      if(transform){
        var val=this.getTranslate();
        pos={
          x:val.x,
          y:val.y
        };
      }else{
        pos = {
          x: that.elem.offsetLeft,
          y: that.elem.offsetTop
        };
      }
      return pos;
    },

위 코드에서 수정한 내용에 주의하세요. 여기에 판단을 추가합니다. 변환 속성을 지원하는 브라우저가 있으면 변환 속성을 사용하여 요소의 값을 수정합니다. , getTranslate 이전 요소의 값을 변경합니다. 에서 얻은 x와 y는 pos의 x와 y에 할당됩니다.

위 코드에서는 브라우저에 따라 동일한 값을 얻기 위해 다양한 방법을 사용합니다. val 값은 요소 변환에서 추출한 getTranslate()에서 가져옵니다. 마찬가지로 아래 setPosition()에서도 if 판단을 설정해야 합니다.

setPosition: function(pos) {
      if (transform) {
        this.elem.style[transform] = 'translate(' + pos.x + 'px' + ',' + pos.y + 'px)';
      } else {
        this.elem.style.left = pos.x + 'px';
        this.elem.style.top = pos.y + 'px';
      }
    },

이 단락에서는 별로 할 말이 없습니다. 단지 다양한 형태로 값을 할당하는 것에 관한 것입니다.

이 시점에서 모듈이 포장되었습니다. 다음으로 전체 코드를 살펴보겠습니다.

;
(function() {
  //私有属性
  var transform = getTransform();
  //构造函数,属于每一个实例
  function Drag(selector) {
    this.elem = typeof selector == 'object' ? selector : document.getElementById(selector);
    //鼠标初始位置
    this.startX = 0;
    this.startY = 0;
    //元素初始位置
    this.sourceX = 0;
    this.sourceY = 0;

    this.init();
  }

  //原型,共有的
  Drag.prototype = {
    constructor: Drag,
    init: function() {
      this.setDrag();
    },

    //用于获取元素当前的位置信息
    getPosition: function() {
      var that = this;
      var pos = {};
      if(transform){
        var val=this.getTranslate();
        pos={
          x:val.x,
          y:val.y
        };
      }else{
        pos = {
          x: that.elem.offsetLeft,
          y: that.elem.offsetTop
        };
      }
      return pos;
    },

    //获取translate值
    getTranslate: function() {
      var val = {};
      var transformValue = document.defaultView.getComputedStyle(this.elem, false)[transform];
      if(transformValue=='none'){
        val={x:0,y:0};
      }else{
        var transformArr = transformValue.match(/-?\d+/g);
        val = {
          x: Number(transformArr[4]),
          y: Number(transformArr[5])
        };
      }


      return val;
    },
    //用来设置当前元素的位置
    setPosition: function(pos) {
      if (transform) {
        this.elem.style[transform] = 'translate(' + pos.x + 'px' + ',' + pos.y + 'px)';
      } else {
        this.elem.style.left = pos.x + 'px';
        this.elem.style.top = pos.y + 'px';
      }
    },

    //该方法用来绑定事件
    setDrag: function() {
      var self = this;
      this.elem.addEventListener('mousedown', start, false);

      function start(event) {

        self.startX = event.pageX;
        self.startY = event.pageY;

        var pos = self.getPosition();

        self.sourceX = pos.x;
        self.sourceY = pos.y;

        document.addEventListener('mousemove', move, false);
        document.addEventListener('mouseup', end, false);
      }

      function move(event) {
        //总体思想:鼠标距浏览器距-鼠标距元素距离
        var currentX = event.pageX; //当前的鼠标x位置
        var currentY = event.pageY; //当前的鼠标y位置

        var distanceX = currentX - self.startX; //鼠标移动的距离x
        var distanceY = currentY - self.startY; //鼠标移动的距离y

        self.setPosition({
          x: self.sourceX + distanceX,
          y: self.sourceY + distanceY
        });

      }

      function end(event) {
        document.removeEventListener('mousemove', move);
        document.removeEventListener('mouseup', end);
      }
    }
  };
  //私有方法,用来获取transform的兼容写法
  function getTransform() {
    var transform = "",
      pStyle = document.createElement('p').style,
      transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'oTransform'],
      i = 0,
      l = transformArr.length;

    for (; i < l; i++) {
      if (transformArr[i] in pStyle) {
        return transform = transformArr[i];
      }
    }
    return transform;
  }
  //暴露在外
  window.Drag = Drag;
})();


new Drag('box');

관련 권장 사항:

javascript 전역 변수 캡슐화 모듈 구현 code_javascript 기술

위 내용은 자체 모듈 인스턴스 캡슐화에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.