用jquery函数逐行连接两个div

643ylb08  于 2023-01-30  发布在  jQuery
关注(0)|答案(1)|浏览(106)

我有两组小测验。
第一组是正确的,但第二组没有显示两点之间的直线。
用户点击左边的点,点击右边的点,然后JavaScript创建一条从第一个元素到第二个元素的“画布”线(抱歉我说英语,这是我的第二语言)。

(function($) {
  $.fn.connect = function(param) {
    var _canvas;
    var _ctx;
    var _lines = new Array(); //This array will store all lines (option)
    var _me = this;
    var _parent = param || document;
    var _lengthLines = $(_parent + ' .group1 .node').length;
    var _selectFirst = null;
    //Initialize Canvas object

    _canvas = $('<canvas/>')
      .attr('width', $(_me).width())
      .attr('height', $(_me).height())
      .css('position', 'absolute');
    $(_parent).prepend(_canvas);
    //$(_canvas).insertBefore(_parent);
    this.drawLine = function(option) {
      //It will push line to array.
      _lines.push(option);
      this.connect(option);

    };

    this.drawAllLine = function(option) {

      /*Mandatory Fields------------------
      left_selector = '.class',
      data_attribute = 'data-right',
      */

      if (option.left_selector != '' && typeof option.left_selector !== 'undefined' && $(option.left_selector).length > 0) {
        $(option.left_selector).each(function(index) {
          var option2 = new Object();
          $.extend(option2, option);
          option2.left_node = $(this).attr('id');
          option2.right_node = $(this).data(option.data_attribute);
          if (option2.right_node != '' && typeof option2.right_node !== 'undefined') {
            _me.drawLine(option2);

          }
        });
      }
    };

    //This Function is used to connect two different div with a dotted line.
    this.connect = function(option) {

      _ctx = _canvas[0].getContext('2d');
      //
      _ctx.beginPath();
      try {
        var _color;
        var _dash;
        var _left = new Object(); //This will store _left elements offset  
        var _right = new Object(); //This will store _right elements offset	
        var _error = (option.error == 'show') || false;
        /*
        option = {
        	left_node - Left Element by ID - Mandatory
        	right_node - Right Element ID - Mandatory
        	status - accepted, rejected, modified, (none) - Optional
        	style - (dashed), solid, dotted - Optional	
        	horizantal_gap - (0), Horizantal Gap from original point
        	error - show, (hide) - To show error or not
        	width - (2) - Width of the line
        }
        */

        if (option.left_node != '' && typeof option.left_node !== 'undefined' && option.right_node != '' && typeof option.right_node !== 'undefined' && $(option.left_node).length > 0 && $(option.right_node).length > 0) {

          //To decide colour of the line
          switch (option.status) {
            case 'accepted':
              _color = '#0969a2';
              break;

            case 'rejected':
              _color = '#e7005d';
              break;

            case 'modified':
              _color = '#bfb230';
              break;

            case 'none':
              _color = 'grey';
              break;

            default:
              _color = 'grey';
              break;
          }

          //To decide style of the line. dotted or solid
          switch (option.style) {
            case 'dashed':
              _dash = [4, 2];
              break;

            case 'solid':
              _dash = [0, 0];
              break;

            case 'dotted':
              _dash = [4, 2];
              break;

            default:
              _dash = [4, 2];
              break;
          }
          /*
          	console.log($(option.left_node));
          	$(option.left_node)
          	$(option.right_node).data('connect',true);
          */
          //If left_node is actually right side, following code will switch elements.
          $(option.right_node).each(function(index, value) {
            _left_node = $(option.left_node);
            _right_node = $(value);

            _left_node.attr('data-connect', true);
            _right_node.attr('data-connect', true);

            if (_left_node.offset().left >= _right_node.offset().left) {
              _tmp = _left_node
              _left_node = _right_node
              _right_node = _tmp;
            }

            //Get Left point and Right Point
            _left.x = _left_node.offset().left + _left_node.outerWidth();
            _left.y = _left_node.offset().top + (_left_node.outerHeight() / 2);
            _right.x = _right_node.offset().left;
            _right.y = _right_node.offset().top + (_right_node.outerHeight() / 2);

            //Create a group
            //var g = _canvas.group({strokeWidth: 2, strokeDashArray:_dash}); 	

            //Draw Line
            var _gap = option.horizantal_gap || 0;

            _ctx.moveTo(_left.x, _left.y);
            if (_gap != 0) {
              _ctx.lineTo(_left.x + _gap, _left.y);
              _ctx.lineTo(_right.x - _gap, _right.y);
            }
            _ctx.lineTo(_right.x, _right.y);

            if (!_ctx.setLineDash) {
              _ctx.setLineDash = function() {}
            } else {
              _ctx.setLineDash(_dash);
            }
            _ctx.lineWidth = option.width || 2;
            _ctx.strokeStyle = _color;
            _ctx.stroke();
          });
          
          //option.resize = option.resize || false;
        } else {
          if (_error) alert('Mandatory Fields are missing or incorrect');
        }
      } catch (err) {
        if (_error) alert('Mandatory Fields are missing or incorrect');
      }
      //console.log(_canvas);
    };

    //It will redraw all line when screen resizes
    $(window).resize(function() {
      console.log(_me);
      _me.redrawLines();
    });

    $(_parent + ' .group1 .node span').click(function() {
      //console.log($(this).attr('data-connect'));
      //[data-use="false"]
      _this = this;
      if ($(_this).attr('data-connect') != 'true' && $(_this).attr('data-use') == 'false') {
        $(_parent + ' .group1 .node span').attr('data-use', 'false');
        $(_this).attr('data-use', 'true');
        _selectFirst = _this;
      } else if ($(_this).attr('data-connect') == 'true') {
        //console.log($(this).attr('data-id'));
        //console.log(entry);
        _lines.forEach(function(entry, index) {
          if ($(_this).attr('data-id') == entry.id_left) {
            $(entry.left_node).attr('data-use', 'false').attr('data-connect', 'false')
            $(entry.right_node).attr('data-use', 'false').attr('data-connect', 'false')
            _lines.splice(index, 1)
          }
        });
        _me.redrawLines();
      }
    });

    $(_parent + ' .group2 .node span[data-use="false"]').click(function() {
      if ($(_parent + ' .group1 .node span[data-use="true"]').length == 1 && _selectFirst != null) {
        if ($(this).attr('data-connect') != 'true') {
          _me.drawLine({
            id_left: $(_selectFirst).attr('data-id'),
            id_right: $(this).attr('data-id'),
            left_node: _selectFirst,
            right_node: this,
            horizantal_gap: 10,
            error: 'show',
            width: 1,
            status: 'accepted'
          });
          $(_selectFirst).attr('data-use', 'false');
          $(_selectFirst).attr('data-connect', 'true');
          $(this).attr('data-use', 'false');
          $(this).attr('data-connect', 'true');
        }
      }
    });

    this.redrawLines = function() {
      _ctx.clearRect(0, 0, $(_me).width(), $(_me).height());
      _lines.forEach(function(entry) {
        entry.resize = true;
        _me.connect(entry);
      });
    };
    return this;
  };
}(jQuery));
.clearfix {
  clear: both;
}

body {
  padding: 0px;
  margin: 0px;
}

.nodes {
  width: 500px
}

.node {
  width: 100px;
  background: #ddd;
  color: #fff;
  margin-bottom: 10px;
}

.group1 span {
  background: #666;
  border-radius: 50%;
  width: 10px;
  height: 10px;
  margin-top: 5px;
}

.group2 span {
  border: 1px solid #666;
  border-radius: 50%;
  width: 10px;
  height: 10px;
  margin-top: 5px;
}

.node span:hover {
  background: #ff0000;
  cursor: pointer;
}

.group1 {
  float: left;
}

.group2 {
  float: right;
}

.group2 .node span {
  float: left;
  position: relative;
  left: -15px;
}

.group1 .node span {
  float: right;
  position: relative;
  right: -15px;
}

.node span[data-connect=true] {
  background: #ff00ff !important;
}

.node span[data-use=true] {
  background: #ff0000 !important;
}
<div id="parentNodes_11">
  <div class="nodes">
    <div class="group1">
      <div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="group2">
      <div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="clearfix"></div>
  </div>
</div>
<br>
<div id="parentNodes_12">
  <div class="nodes">
    <div class="group1">
      <div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="group2">
      <div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="clearfix"></div>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript">
  $(document).ready(function() {
    $('#parentNodes_11 .nodes').connect('#parentNodes_11');
    $('#parentNodes_12 .nodes').connect('#parentNodes_12');
  });
</script>
ffscu2ro

ffscu2ro1#

这是由于使用绝对坐标代替相对坐标,所以你的线条不适合画布。
您可以只执行父偏移调整,其工作方式如下:

(function($) {
  $.fn.connect = function(param) {
    var _canvas;
    var _ctx;
    var _lines = new Array(); //This array will store all lines (option)
    var _me = this;
    var _parent = param || document;
    var _lengthLines = $(_parent + ' .group1 .node').length;
    var _selectFirst = null;
    //Initialize Canvas object

    _canvas = $('<canvas/>')
      .attr('width', $(_me).width())
      .attr('height', $(_me).height())
      .css('position', 'absolute');
    $(_parent).prepend(_canvas);
    //$(_canvas).insertBefore(_parent);
    this.drawLine = function(option) {
      //It will push line to array.
      _lines.push(option);
      this.connect(option);

    };

    this.drawAllLine = function(option) {

      /*Mandatory Fields------------------
      left_selector = '.class',
      data_attribute = 'data-right',
      */

      if (option.left_selector != '' && typeof option.left_selector !== 'undefined' && $(option.left_selector).length > 0) {
        $(option.left_selector).each(function(index) {
          var option2 = new Object();
          $.extend(option2, option);
          option2.left_node = $(this).attr('id');
          option2.right_node = $(this).data(option.data_attribute);
          if (option2.right_node != '' && typeof option2.right_node !== 'undefined') {
            _me.drawLine(option2);

          }
        });
      }
    };

    //This Function is used to connect two different div with a dotted line.
    this.connect = function(option) {

      _ctx = _canvas[0].getContext('2d');
      //
      _ctx.beginPath();
      try {
        var _color;
        var _dash;
        var _left = new Object(); //This will store _left elements offset  
        var _right = new Object(); //This will store _right elements offset 
        var _error = (option.error == 'show') || false;
        /*
        option = {
            left_node - Left Element by ID - Mandatory
            right_node - Right Element ID - Mandatory
            status - accepted, rejected, modified, (none) - Optional
            style - (dashed), solid, dotted - Optional  
            horizantal_gap - (0), Horizantal Gap from original point
            error - show, (hide) - To show error or not
            width - (2) - Width of the line
        }
        */

        if (option.left_node != '' && typeof option.left_node !== 'undefined' && option.right_node != '' && typeof option.right_node !== 'undefined' && $(option.left_node).length > 0 && $(option.right_node).length > 0) {

          //To decide colour of the line
          switch (option.status) {
            case 'accepted':
              _color = '#0969a2';
              break;

            case 'rejected':
              _color = '#e7005d';
              break;

            case 'modified':
              _color = '#bfb230';
              break;

            case 'none':
              _color = 'grey';
              break;

            default:
              _color = 'grey';
              break;
          }

          //To decide style of the line. dotted or solid
          switch (option.style) {
            case 'dashed':
              _dash = [4, 2];
              break;

            case 'solid':
              _dash = [0, 0];
              break;

            case 'dotted':
              _dash = [4, 2];
              break;

            default:
              _dash = [4, 2];
              break;
          }
          /*
            console.log($(option.left_node));
            $(option.left_node)
            $(option.right_node).data('connect',true);
          */
          //If left_node is actually right side, following code will switch elements.
          $(option.right_node).each(function(index, value) {
            _left_node = $(option.left_node);
            _right_node = $(value);

            _left_node.attr('data-connect', true);
            _right_node.attr('data-connect', true);

            if (_left_node.offset().left >= _right_node.offset().left) {
              _tmp = _left_node
              _left_node = _right_node
              _right_node = _tmp;
            }

            //Get Left point and Right Point
            _left.x = _left_node.offset().left + _left_node.outerWidth();
            _left.y = _left_node.offset().top + (_left_node.outerHeight() / 2) - _left_node.parents('.nodes').offset().top;
            _right.x = _right_node.offset().left;
            _right.y = _right_node.offset().top + (_right_node.outerHeight() / 2) - _right_node.parents('.nodes').offset().top; 

            //Create a group
            //var g = _canvas.group({strokeWidth: 2, strokeDashArray:_dash});   

            //Draw Line
            var _gap = option.horizantal_gap || 0;

            _ctx.moveTo(_left.x, _left.y);
            if (_gap != 0) {
              _ctx.lineTo(_left.x + _gap, _left.y);
              _ctx.lineTo(_right.x - _gap, _right.y);
            }
            _ctx.lineTo(_right.x, _right.y);

            if (!_ctx.setLineDash) {
              _ctx.setLineDash = function() {}
            } else {
              _ctx.setLineDash(_dash);
            }
            _ctx.lineWidth = option.width || 2;
            _ctx.strokeStyle = _color;
            _ctx.stroke();
          });
          
          //option.resize = option.resize || false;
        } else {
          if (_error) alert('Mandatory Fields are missing or incorrect');
        }
      } catch (err) {
        if (_error) alert('Mandatory Fields are missing or incorrect');
      }
      //console.log(_canvas);
    };

    //It will redraw all line when screen resizes
    $(window).resize(function() {
      console.log(_me);
      _me.redrawLines();
    });

    $(_parent + ' .group1 .node span').click(function() {
      //console.log($(this).attr('data-connect'));
      //[data-use="false"]
      _this = this;
      if ($(_this).attr('data-connect') != 'true' && $(_this).attr('data-use') == 'false') {
        $(_parent + ' .group1 .node span').attr('data-use', 'false');
        $(_this).attr('data-use', 'true');
        _selectFirst = _this;
      } else if ($(_this).attr('data-connect') == 'true') {
        //console.log($(this).attr('data-id'));
        //console.log(entry);
        _lines.forEach(function(entry, index) {
          if ($(_this).attr('data-id') == entry.id_left) {
            $(entry.left_node).attr('data-use', 'false').attr('data-connect', 'false')
            $(entry.right_node).attr('data-use', 'false').attr('data-connect', 'false')
            _lines.splice(index, 1)
          }
        });
        _me.redrawLines();
      }
    });

    $(_parent + ' .group2 .node span[data-use="false"]').click(function() {
      if ($(_parent + ' .group1 .node span[data-use="true"]').length == 1 && _selectFirst != null) {
        if ($(this).attr('data-connect') != 'true') {
          _me.drawLine({
            id_left: $(_selectFirst).attr('data-id'),
            id_right: $(this).attr('data-id'),
            left_node: _selectFirst,
            right_node: this,
            horizantal_gap: 10,
            error: 'show',
            width: 1,
            status: 'accepted'
          });
          $(_selectFirst).attr('data-use', 'false');
          $(_selectFirst).attr('data-connect', 'true');
          $(this).attr('data-use', 'false');
          $(this).attr('data-connect', 'true');
        }
      }
    });

    this.redrawLines = function() {
      _ctx.clearRect(0, 0, $(_me).width(), $(_me).height());
      _lines.forEach(function(entry) {
        entry.resize = true;
        _me.connect(entry);
      });
    };
    return this;
  };
}(jQuery));
.clearfix {
  clear: both;
}

body {
  padding: 0px;
  margin: 0px;
}

.nodes {
  width: 500px
}

.node {
  width: 100px;
  background: #ddd;
  color: #fff;
  margin-bottom: 10px;
}

.group1 span {
  background: #666;
  border-radius: 50%;
  width: 10px;
  height: 10px;
  margin-top: 5px;
}

.group2 span {
  border: 1px solid #666;
  border-radius: 50%;
  width: 10px;
  height: 10px;
  margin-top: 5px;
}

.node span:hover {
  background: #ff0000;
  cursor: pointer;
}

.group1 {
  float: left;
}

.group2 {
  float: right;
}

.group2 .node span {
  float: left;
  position: relative;
  left: -15px;
}

.group1 .node span {
  float: right;
  position: relative;
  right: -15px;
}

.node span[data-connect=true] {
  background: #ff00ff !important;
}

.node span[data-use=true] {
  background: #ff0000 !important;
}
<div id="parentNodes_11">
  <div class="nodes">
    <div class="group1">
      <div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="group2">
      <div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="clearfix"></div>
  </div>
</div>
<br>
<div id="parentNodes_12">
  <div class="nodes">
    <div class="group1">
      <div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="group2">
      <div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
      <div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
      <div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
    </div>
    <div class="clearfix"></div>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript">
  $(document).ready(function() {
    $('#parentNodes_11 .nodes').connect('#parentNodes_11');
    $('#parentNodes_12 .nodes').connect('#parentNodes_12');
  });
</script>

相关问题