Содержание всплывающей подсказки удваивается при каждом открытии

Я использую Tooltipster, чтобы показать список элементов, на которые пользователь может щелкнуть, чтобы ввести элемент в текстовое поле. Когда всплывающая подсказка создана, я получаю список элементов с selectors = $("ul.alternates > li");

Однако каждый раз, когда открывается всплывающая подсказка, элемент, по которому щелкнули, будет вставлен соответствующее число раз; например, если я открывал всплывающую подсказку 5 раз, то нажатый элемент будет вставлен 5 раз. Я пытался удалить значение переменной после закрытия всплывающей подсказки functionAfter: function() {selectors = null;} но это не имело никакого эффекта.

У меня есть Codepen ошибки здесь, которая должна прояснить ситуацию.

// set list to be tooltipstered
$(".commands > li").tooltipster({
 interactive: true,
 theme: "tooltipster-light",
 functionInit: function(instance, helper) {
  var content = $(helper.origin).find(".tooltip_content").detach();
  instance.content(content);
 },
 functionReady: function() {
  selectors = $("ul.alternates > li");
  $(selectors).click(function() {
   var sampleData = $(this).text();
   insertText(sampleData);
  });
 },
 // this doesn't work
 functionAfter: function() {
  selectors = null;
 }
});

// Begin inputting of clicked text into editor
function insertText(data) {
 var cm = $(".CodeMirror")[0].CodeMirror;
 var doc = cm.getDoc();
 var cursor = doc.getCursor(); // gets the line number in the cursor position
 var line = doc.getLine(cursor.line); // get the line contents
 var pos = {
  line: cursor.line
 };
 if (line.length === 0) {
  // check if the line is empty
  // add the data
  doc.replaceRange(data, pos);
 } else {
  // add a new line and the data
  doc.replaceRange("\n" + data, pos);
 }
}

var code = $(".codemirror-area")[0];
var editor = CodeMirror.fromTextArea(code, {
 mode: "simplemode",
 lineNumbers: true,
 theme: "material",
 scrollbarStyle: "simple",
 extraKeys: { "Ctrl-Space": "autocomplete" }
});
body {
 margin: 1em auto;
 font-size: 16px;
}
.commands {
 display: inline-block;
}
.tooltip {
 position: relative;
 opacity: 1;
 color: inherit;
}
.alternates {
 display: inline;
 margin: 5px 10px;
 padding-left: 0;
}

.tooltipster-content .alternates {
 li {
  list-style: none;
  pointer-events: all;
  padding: 15px 0;
  cursor: pointer;
  color: #333;
  border-bottom: 1px solid #d3d3d3;
  span {
   font-weight: 600;
  }
  &:last-of-type {
   border-bottom: none;
  }
 }
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.25.2/theme/material.min.css" rel="stylesheet"/>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/235651/jquery-3.2.1.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/235651/tooltipster.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.25.2/codemirror.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.25.2/addon/mode/simple.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.25.2/addon/hint/show-hint.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.25.2/addon/scroll/simplescrollbars.js"></script>
<div class="container">
 <div class="row">
   <div class="col-md-6">
   <ul class="commands">
   <li><span class="command">Hover for my list</span><div class="tooltip_content">
    <ul class="alternates">
     <li>Lorep item</li>
     <li>Ipsum item</li>
     <li>Dollar item</li>
    </ul>
   </li>
   </div>
   </ul>
  </div>
  <div class="col-md-6">
   <textarea class="codemirror-area"></textarea>
  </div>
 </div>
</div>

2 ответа

Решение

Tooltipster-х functionReady срабатывает каждый раз, когда всплывающая подсказка добавляется в DOM, что означает, что каждый раз, когда пользователь наводит курсор на список, вы снова связываете событие.

Вот два способа предотвратить это:

  1. Прикрепите обработчик кликов ко всему, что существует в DOM, до отображения всплывающей подсказки. (Положите это за tooltipspter(), Не нужно использовать functionReady.)

Пример:

$(document).on('click','ul.alternates li', function(){
    var sampleText = $(this).text();
    insertText(sampleText);
})

Вот кодекс

  1. Отсоединяйте и связывайте событие каждый раз, когда вызывается functionReady.

Пример:

functionReady: function() {
    selectors = $("ul.alternates > li");
    $(selectors).off('click').on('click', function() {
        var sampleData = $(this).text();
        insertText(sampleData);
    });
}

Вот Codpen.

Вы связываете новые клики каждый раз. Я бы предложил другой стиль кода, но в этом формате вы можете просто добавить до события click

$(selectors).unbind('click');

Тогда сделайте щелчок снова..

Другие вопросы по тегам