Как создать плагин jQuery с параметрами Включения и отключения?

#jquery #jquery-plugins

Вопрос:

Я попытался создать плагин jquery Comment , который позволяет пользователю закреплять блок комментариев в любом месте экрана.

Однако я понятия не имею, как включить или отключить этот плагин по требованию, так как теперь он включен по умолчанию; Я хочу установить опцию, чтобы включить или отключить его, скажем, при нажатии кнопки.

Вот мой скрипт плагина: comment_plugin.js

 ;
(function(window, $) {
  "use strict";

  var style = document.createElement("link")
  style.rel = "stylesheet"
  style.href = "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css"
  document.head.appendChild(style)

  $.comment = function(options) {
    var script = document.createElement("script");
    script.src = 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js';
    document.head.append(script);

    var defaultConfig = {
      Enable: true,
      maxComment: 10,
      maxCollapse: 3,
      Cursor: "pointer",
      Area: 'body',
      ExcludeArea: '',
      CommentAdded: {}, // method called on first comment added
      CommentHidden: function() {}, // method called on hide comment
      CommentRemoved: function() {}, // method called on comment or replied comment removed
      CommentReplied: function() {}, // method called on reply to any comment
      CommentMoved: function() {}, // method called on move position of comment
      dataComment: [], // data for set default comment
    };


    var plugin = this

    plugin.init = function() {
      var settings = $.extend({}, defaultConfig, options);
      $.data(document, 'comment', settings);
    }
    plugin.init();

    var config = $.extend({}, defaultConfig, options);

    $(config.Area).css({
      cursor: config.Cursor
    }).on('click', function(event) {

      var target = event.target

      if (
        $(target).is('input') ||
        $(target).is('p.comment_content') ||
        $(target).is('p') ||
        $(target).is('.comment-box *') ||
        $(target).is('.comment-number') ||
        $(target).is('.comment-number *') ||
        !config.Enable ||
        $(target).is(config.ExcludeArea)
      ) {
        if ($(target).is('.comment-number')) {
          $(target).next().toggle()
        } else if ($(target).is('.comment-number *')) {
          $(target).parents('.comment-number').next().toggle()
        }

        return;
      }

      $('.comment-box').hide()

      var target = event.target
      var x = event.pageX   2
      var y = event.pageY - 30

      var count = $('.comment-number').length ? $('.comment-number').length   1 : 1;

      var max_count = $('.comment-number').length ? $('.comment-number').length   1 : 1;

      if ($('.comment-number').length > 0) {
        var arrComment = []
        $('.comment-number').each(function() {
          var maxNum = $(this).find('b').text()
          arrComment.push(parseInt(maxNum))
        })
      }
      // find the last comment number
      if (arrComment) {
        count = arrComment.reduce((max, val) => max > val ? max : val)   1
      }

      /* handle maximun comment allowed */
      if (max_count > config.maxComment amp;amp; config.maxComment != 0) {
        alert('Only '   config.maxComment   ' comments allowed!')
        return;
      }

      /* comment input box Area */
      var div = $(`
        <span id="comment_${count}" class="comment-number"><b>${count}</b></span>
        `)

      $(div).css({
        position: 'absolute',
        top: y,
        left: x,
        cursor: 'pointer'
      })

      $(this).append(div)

      setTimeout(function() {
        $(div).draggable();
      }, 1000)

      // comment box
      var x_comment = x   60
      var y_comment = y

      var comment_div = $(`
        <div id="comment_box_${count}" class="comment-box">
          <div class="comment-list">
          </div>

          <div class="comment-input-box">
            <textarea name="" id="comment-input-${count}" class="comment-input" style="width: 100%;" placeholder="Add a comment"></textarea>
          </div>

          <div class="button-comment">
            <button class="btn btn-secondary btn-comment-cancel">Cancel</button>
            <button class="btn btn-info btn-comment-post">Post</button>
          </div>
          
        </div>
        `)

      $(comment_div).css({
        position: 'absolute',
        top: y_comment,
        left: x_comment,
        cursor: 'pointer'
      })

      $(this).append(comment_div)
      $('#comment-input-'   count).focus()

      // handl post comment
      $(document).on('click', '.btn-comment-post', function() {
        var comment = $(this).parent().prev().find('textarea').val()

        if (comment != '') {
          var comment_item = `
          <div class="comment_item">
          <div class="comment-header">
          <span class="initial_name">N</span>
          <p class="commentor_name">Narun</p>
          <p class="comment-time">30 minutes ago</p>
          <a href="#" class="comment-more-action" data-toggle="dropdown" style="padding: 10px;">
            <img src="../images/icon/comment_more_action_icon.svg" class="comment-more-action" alt="">
          </a>
          <div class="dropdown-menu comment-dropdown-action">
            <a class="dropdown-item hide-comment" href="#"><i class="far fa-eye-slash"></i>amp;nbsp;amp;nbsp;Hide Comment</a>
            <a class="dropdown-item edit-comment" href="#"><i class="far fa-edit"></i>amp;nbsp;amp;nbsp;Edit Comment</a>
            <a class="dropdown-item remove-comment" href="#"><i class="far fa-trash-alt"></i>amp;nbsp;amp;nbsp;Remove Comment</a>
          </div>
          </div>
          <p class="comment_content">
          ${comment}
          </p>
          </div>
          `
          // comment edit or new comment
          var comment_edit = $(this).parents('.comment-box').find('.comment-list').find('.comment_item[data-editting]')
          if (comment_edit.length > 0) {
            $(this).parents('.comment-box').find('.comment-list').find('[data-editting]').replaceWith(comment_item)
            $(this).parents('.comment-box').find('.comment-list').find('[data-editting]').removeAttr('data-editting')

          } else {
            $(this).parents('.comment-box').find('.comment-list').append(comment_item)
          }

          // $(this).parents('.comment-box').find('.comment-list').append(comment_item)
          $(this).parent().prev().find('textarea').val('')
          $(this).parent().prev().find('textarea').attr('placeholder', 'Reply')
          $(this).parent().prev().find('textarea').focus()
          comment_item = ''
        }

        // handle long comment
        var item_count = $(this).parents('.comment-box').find('.comment-list').find('.comment_item').length
        var show_more = ''
        var hide_more = ''
        if (item_count > config.maxCollapse) {
          show_more = '<a href="" class="show-more-comment" >show another '   (item_count - 1)   ' comments</a>'

          if (!$(this).parents('.comment-box').find('.comment_item:first').next().is('a.show-more-comment')) {
            $(this).parents('.comment-box').find('.comment_item:first').append(show_more)
          } else {
            $(this).parent().prev().parent().find('a.show-more-comment').remove() //.html(show_more)
            $(this).parents('.comment-box').find('.comment_item:first').append(show_more)
          }


          $(this).parents('.comment-box').find('.comment_item').not(':first-child').slideUp(function() {
            // var show_hide = $.parseHTML($(show_more))
            // $(show_hide).find('.show_hide').text('hide another')
          })
          show_more = ''
        } else if (item_count == 1) {
          // Handle method on first comment added
          // if(config.CommentAdded){
          //   config.CommentAdded()
          // }
        }

        $('.show-more-comment').not(':last-child').hide()



      })


      // handle show more comment
      $(document).on('click', 'a.show-more-comment', function(e) {
        e.preventDefault()
        $('.comment_item').show()
        $(this).hide()
      })

      setTimeout(function() {
        $(div).draggable({
          start: function(event, ui) {
            $(this).next().hide()
          },
          stop: function(event, ui) {
            var finalOffset = $(this).offset();
            var finalxPos = finalOffset.left   60;
            var finalyPos = finalOffset.top;

            $(this).next().css({
              top: finalyPos,
              left: finalxPos
            })
          }

        });
      }, 10)


    })

    $(document).on('keydown', function(event) {
      if (event.key == 'Escape') {
        $('.comment-box').hide()
      }
    })

    // handle hide comment
    $(document).on('click', '.hide-comment', function(e) {
      e.preventDefault()
      $(this).parents('.comment-box').hide()
      if (config.CommentHidden) {
        config.CommentHidden()
      }
    })


  }

  /* action on more action */

  $(document).on('click', '.remove-comment', function(e) {
    e.preventDefault()
    // config.CommentRemoved()

    var comment_item_count = $(this).parents('.comment-list').find('.comment_item').length

    if (comment_item_count > 0 amp;amp; comment_item_count == 1) {
      $(this).parents('.comment-box').prev().remove()
      $(this).parents('.comment-box').remove()
    } else {
      $(this).parents('.comment_item').remove()
    }

  })

  // handle edit comment
  $(document).on('click', '.edit-comment', function(e) {
    e.preventDefault()
    // config.CommentRemoved()
    var comment_content = $(this).parents('.comment-header').next().text()
    $(this)
      .parents('.comment-list')
      .next()
      .find('textarea.comment-input')
      .val(comment_content.trim())
    $(this).parents('.comment_item').attr('data-editting', true)
  })


  var disableComment = function() {

    return 'disable'
  }

  return this;
})(window, jQuery)

$.comment.init = function(callback) {
  return $.data(document, 'comment');
}


$(document).ready(function() {
  $.comment({
    Enable: true,
    Area: 'body',
    maxComment: 0,
    maxCollapse: 3,
    // CommentAdded: function(){
    //  alert("comment added")
    // },
    CommentHidden: function() {
      alert('comment is hide')
    },
    // dataComment: dataComment

  })
}) 
 .comment-icon {
  width: 30px;
  height: 30px;
  border-radius: 100%;
  border: 2.45px solid #e7ad56;
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
}

.comment-icon:before {
  position: absolute;
  content: "";
  top: 19px;
  left: -9px;
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 15px solid #e7ad56;
  transform: rotate(50deg);
}

.comment-icon:after {
  position: absolute;
  content: "";
  top: 19px;
  left: -5px;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 12px solid #fff;
  transform: rotate( 50deg);
}

.comment-box,
.comment-box textarea {
  /*display: flex;*/
  width: 260px;
  background: #E9F2FC;
  padding: 15px;
  /*resize: none;*/
}

.comment-box textarea {
  border: 0 !important;
  padding: 8px !important;
  height: 30px;
  outline: none;
}

.comment-box .comment-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.comment-box .comment-header p {
  margin-bottom: 0;
}

.comment-box .initial_name {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 12px;
  border-radius: 100%;
  padding: 12px;
  background: #E7AD56;
  color: #fff;
}

.comment-box .comment-time {
  color: #b3bfc6;
}

.comment-box img.comment-more-action {
  margin-top: -15px;
}

.comment-box .comment_item {
  border-bottom: 1px solid #CCC;
}


/*.comment-box .comment_item:nth-child(2){
  border-top: 1px solid #CCC;
  border-bottom: 1px solid #CCC;
}
*/

.comment-box .comment_item:last-child {
  margin-bottom: 10px;
}

.comment-box .comment_item:not(:first-child) {
  padding-top: 10px;
}


/* another style  */

.comment-number {
  box-sizing: border-box;
  display: inline-grid;
  place-content: center;
  margin: .25rem;
  /* flexible width with logical properties */
  inline-size: max-content;
  min-inline-size: 2.8rem;
  padding: 0 .75rem;
  /* keeps the aspect ratio */
  aspect-ratio: 1;
  color: #444;
  font-family: 'Open Sans', Arial;
  /* SVG background */
  background-image: url('data:image/svg xml;UTF-8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -3 51 53"><path d="M4 35 A24 24 0 1 1 12 43L1 47z" fill="white" stroke="gold" stroke-width="3" /></svg>');
  background-repeat: no-repeat;
  background-position: center;
}

.comment-number * {
  font-weight: normal;
}

.button-comment {
  float: right;
  margin-top: 15px;
}

.button-comment button {
  filter: none;
  border-radius: 5px;
  font-size: 11px;
  height: 32px;
}

.button-comment .btn-comment-cancel {
  background: #FFF !important;
  border: 1px solid;
  color: #000;
}

.button-comment .btn-comment-post {
  margin-left: 5px;
  background: #18a0fb !important;
}

@supports (not (aspect-ratio: 1)) {
  /* if aspect-ratio is not supported then use 
    * padding-bottom in a ::before pseudoelement
    */
  .comment-number *::before {
    content: "";
    display: inline-block;
    vertical-align: middle;
    padding-bottom: calc(100%   1.5rem);
  }
}

a.comment-more-action {
  border-radius: 3px;
}

a.comment-more-action img {
  padding-top: 10px !important;
}

.zindex-1 {
  z-index: 1;
  /*border: 1px solid #000;*/
}


/*a.comment-more-action:hover {
  background: #d7dfe8;
}
.comment-dropdown-action a {
  padding: 12px;
}
.comment-dropdown-action a:hover {
  background: #d7dfe8;
}
*/ 
 <!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
  <title>Document</title>
</head>

<body style="height: 200px">

  <p>Form Application</p>

  <button class="btn btn-primary enable-comment">Enable comment</button>
  <button class="btn btn-secondary disable-comment">Disable comment</button>
</body>

</html> 

Я бы хотел, чтобы это работало как $('.enable-comment').click(function(){$.comment('enable'})}) для включения плагина комментариев, так и $('.disable-comment').click(function(){$.comment('disable'})}) для отключения плагина комментариев.

Как я могу этого достичь ? Спасибо

Ответ №1:

Самый простой способ-использовать переменную, чтобы проверить, может ли код выполняться или нет.

 $('.enable-comment').click(function(){ var runCode = 'yes';});
 $('.disable-comment').click(function(){ var runCode = 'no';});
 

А затем просто проверьте это в своей функции

     (function(window, $) { 
        if (runCode == 'yes') {
           ...//run your code
        }
        else{
          ...///do something if code wont run
         };
 

ОТРЕДАКТИРОВАНО в качестве вашего комментария.

Вы можете использовать onclick="toggleComments" или вы можете использовать

 $('.enable-comment').click(function(){ toggleComments(runCode);});
 

Вы можете включать/выключать комментарии при загрузке страницы.

 $(document).ready(function (){
    var runCode = 'yes';
});
 

и функция включения/выключения комментариев

 function toggleComments(runCode)
{
    if (runCode == 'yes')
    {
        runCode = 'No'
    }else{
        runCode = 'yes'
    }
}
 

Вам просто нужно ввести проверку кода varrunCode в свой код, как я упоминал выше.

Комментарии:

1. Большое вам спасибо, однако я хочу включить или отключить плагин на лету; Я подумал о том, чтобы изменить опцию включения плагина, и плагин должен действовать соответственно. 🙂

2. что значит «на лету»? при загрузке страницы?

3. Я имел в виду, что плагин может быть включен и отключен в любое время, например: когда плагин уже был включен с помощью нажатия кнопки «Включить», а затем мы также можем отключить с помощью нажатия кнопки «Отключить» и наоборот. Спасибо

4. большое спасибо, я понимаю эту концепцию, но все еще не знаю, как ее реализовать в моем текущем коде плагина. Ищете возможность изменить его текущие параметры, а затем повторно его инициализировать.