Javascript: уничтожить экземпляр tippy.js
У меня есть следующий код, который показывает всплывающую подсказку, содержащую динамические данные. Работает нормально, но показывает одинаковую подсказку для всех.
я использовал tip._tippy.destroy();
немного не сработало.
<div id="template" style="display: none;">
Loading a tooltip...
</div>
Элемент, на котором показана подсказка выше:
<span class="more-tags otherPostTags" data-postId="{{$post->id}}">...</span>
Js:
const template = document.querySelector('#template')
const initialText = template.textContent
const tip = tippy('.otherPostTags', {
animation: 'shift-toward',
arrow: true,
html: '#template',
onShow() {
const content = this.querySelector('.tippy-content')
if (tip.loading || content.innerHTML !== initialText) return
tip.loading = true
node = document.querySelectorAll('[data-tippy]');
let id = node[0].dataset.postid;
$.ajax({
url: '/get/post/'+id+'/tags',
type: 'GET',
success: function(res){
let preparedMarkup = '';
res.tags.map(function(item) {
preparedMarkup +=
'<span class="orange-tag" style="background-color: '+item.color+'">'+
item.name +
'</span>';
});
content.innerHTML = preparedMarkup;
tip.loading = false
},
});
},
onHidden() {
const content = this.querySelector('.tippy-content');
content.innerHTML = initialText;
},
});
При наведении курсора всплывающее окно показывает с тегами, поступающими из базы данных, но оно показывает те же теги / данные при наведении курсора, данные отличаются, но отображаются всплывающие подсказки, появляющиеся при первом наведении.
2 ответа
Ваша проблема здесь:
node = document.querySelectorAll('[data-tippy]');
let id = node[0].dataset.postid;
Вместо того, чтобы выбирать текущий элемент, вы всегда выбираете один и тот же элемент (node[0]
).
Вы можете использовать аргумент функции обратного вызова, чтобы щелкнуть текущий элемент (onShow
Первый аргумент содержит ссылку на объект, который имеет ссылку на исходный элемент, в моем примере - tip.reference
). Пример ниже:
tippy.setDefaults({
arrow: true,
delay: 240,
theme: 'my-tippy',
onShow(tip) {
console.log('Post id: ' + $(tip.reference).data('postid'));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/tippy.js@3/dist/tippy.all.min.js"></script>
<button data-tippy="Tooltip" data-postId="1">Post 1</button>
<button data-tippy="Another tooltip" data-postId="2">Post 2</button>
<button data-tippy="Another tooltip" data-postId="3">Post 3</button>
Это потому, что ключевое слово const создает переменную только для чтения.
Константы имеют блочную область, во многом как переменные, определенные с помощью оператора let.
Значение константы не может быть изменено путем переназначения и не может быть повторно объявлено.
Вы должны изменить это на var
или же let
потому что это должно быть mutable
(который const
нет).
var
оператор объявляет переменную, опционально инициализируя ее значением.
let
оператор объявляет локальную переменную области видимости, опционально инициализируя ее значением.
Теория в стороне, вы должны изменить const tip
в var tip
- чтобы обновить и / или уничтожить его.
в соответствии со следующей разметкой - которая все еще немного узкая, поскольку она не является отображаемым HTML-выводом разметки одного целого сообщения, так как это потребуется для надежного воспроизведения проблемы:
<span class="more-tags otherPostTags" data-postId="{{$post->id}}">...</span>
можно (возможно, в рамках источника события) получить идентификатор:
var id = parseInt($(this).data('postId'));
наиболее распространенный метод для обработки идентификаторов будет использовать атрибут id
(например, с одинаковым post_id post_45
) всего узла сообщения в сочетании с
var id = parseInt($(selector).attr('id').replace('post_', ''));
Суть в том, что без полной разметки одного поста, я могу только намеки на синтаксис одинаково $(this).parent().parent()...
, что может потребоваться для получения дескриптора, который необходимо будет выбрать относительно источника события.