Javascript:Tippy.js 不适用于动态内容

Gam*_*mer 7 javascript jquery tippyjs

我有以下提示,悬停时 Ajax 调用会去获取数据,创建内容并显示它。但它不适用于动态内容,因为在页面加载

<span class="more-tags otherPostTags" data-postId="{{$post->id}}">...</span>

在页面上是静态的,但在选项卡中也是动态的。

所以下面的代码适用于静态

<span class="more-tags otherPostTags" data-postId="{{$post->id}}">...</span>

但不适用于动态。

<div id="template" style="display: none;">
    Loading a new image...
</div>

<span class="more-tags otherPostTags" data-postId="{{$post->id}}">...</span>
Run Code Online (Sandbox Code Playgroud)

提示 jquery :

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
            },
            error: function(error) {
                console.log(error);
                content.innerHTML = 'Loading failed';
                tip.loading = false
            },
        });
    },
    onHidden() {
        const content = this.querySelector('.tippy-content');
        content.innerHTML = initialText;

    },
    popperOptions: {
        modifiers: {
            preventOverflow: {
                enabled: false
            },
            hide: {
                enabled: false
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

Sno*_*all 8

这在较新的 Tippy 版本中发生了变化。

您需要delegatetippy.js以下位置导入方法:

import { delegate } from 'tippy.js';
Run Code Online (Sandbox Code Playgroud)

然后使用根元素上的委托方法启动您的提示工具提示,并通过target道具设置将具有实际工具提示的元素的选择器:

delegate( '#root', {
  target: '[data-tippy-content]'
} );
Run Code Online (Sandbox Code Playgroud)

确保该#root元素确实存在于您的应用程序中或使用其他任何内容body,例如。然后确保为实际元素提供data-tippy-content属性或相应地更改target选择器。


T.J*_*der 5

如果您希望 Tippy 在新元素上激活,则需要使用事件委托。该毛尖文档涵盖本(令人沮丧的,没有锚链接,搜索“事件代理”)。您使用父容器元素,然后告诉 Tippy 使用哪个选择器来匹配子元素。文档中的示例是:

tippy('#parent', {
  target: '.child'
})
Run Code Online (Sandbox Code Playgroud)

...因此,对于您的示例,请使用所有.otherPostTags元素都在其中的容器(document.body在最坏的情况下)并.otherPostTags用作target

tippy('selectorForParentElement', {
  target: '.otherPostTags'
});
Run Code Online (Sandbox Code Playgroud)

现场示例:

tippy('#parent', {
  target: '.child'
})
Run Code Online (Sandbox Code Playgroud)
tippy('selectorForParentElement', {
  target: '.otherPostTags'
});
Run Code Online (Sandbox Code Playgroud)
tippy('#container', {
  target: '.otherPostTags'
});
var counter = 0;
var timer = setInterval(function() {
  ++counter;
  var tag = document.createElement("span");
  tag.title = "Tip for span #" + counter;
  tag.className = "otherPostTags";
  tag.innerHTML = "Span #" + counter;
  document.getElementById("container").appendChild(tag);
  if (counter === 6) {
    clearInterval(timer);
  }
}, 250);
Run Code Online (Sandbox Code Playgroud)