5

我在我的网站上安装了 Tooltipster ,但它不适用于动态添加的内容。

您可以在“SORT GAMES BY YOUR CHOICE(NEWEST GAMES BY DEFAULT)”框中看到它,当我选择按“最新优先”、“最受欢迎”等排序时...生成内容时,Tooltipster 看不到那个内容。不知何故,我必须告诉 Tooltipster 该内容。

这是工具提示代码:

<head></head>
    <link rel="stylesheet" type="text/css" href="http://www.heroplaysonline.com/css/tooltipster.css" />
    <script type="text/javascript" src="http://www.heroplaysonline.com/js/jquery.tooltipster.min.js"></script>
<script>
    $(document).ready(function() {
        $('.tooltip').tooltipster({
            position: 'bottom-left',
            contentAsHTML: 'true',
            animation: 'grow',
            theme: '.my-custom-theme'
        });
    });
</script>

这是生成内容的脚本:

jQuery(document).ready(function($){
  $.fn.vAlign = function() {
    return this.each(function(i){
      var ah = $(this).height();
      var ph = $(this).parent().height();
      var mh = Math.ceil((ph-ah) / 2);
      $(this).css('margin-top', mh);
    });
  };

  $('#sortable-game-box-order select').change(function() {
    var sorturl = $(this).attr("value");
    var loaderheight = $('#sortable-game-box-inner-content').height();
    $('#sortable-game-box-loader').css('height', loaderheight+13);
    $('#sortable-game-box-loader-content').css('height', loaderheight+13);
    $('#sortable-game-box-loader-content img').vAlign();
    $('#sortable-game-box-list').hide();
    $('#sortable-game-box-loader').show();
    $('#sortable-game-box-inner').load(sorturl + ' #sortable-game-box-inner-content', function() {
      $('#sortable-game-box-loader').hide();
      $('#sortable-game-box-list').show();      
    });
  });
});

这是 js 的代码,其中内容是动态生成的,并且 tooltipster 可以工作,但我无法为我的代码转换它。

(function($){'use strict';Date.now=Date.now||function(){return+new Date();};$.ias=function(options)
{var opts=$.extend({},$.ias.defaults,options);var util=new $.ias.util();var paging=new $.ias.paging(opts.scrollContainer);var hist=(opts.history?new $.ias.history():false);var _self=this;function call_tooltip()
{$('.tooltip_cls').tooltipster({animation:'grow',theme:'.my-custom-theme'});}
function init()
{call_tooltip();var pageNum;paging.onChangePage(function(pageNum,scrollOffset,pageUrl){if(hist){hist.setPage(pageNum,pageUrl);}
opts.onPageChange.call(this,pageNum,pageUrl,scrollOffset);});reset();if(hist&&hist.havePage()){stop_scroll();pageNum=hist.getPage();util.forceScrollTop(function(){var curTreshold;if(pageNum>1){paginateToPage(pageNum);curTreshold=get_scroll_treshold(true);$('html, body').scrollTop(curTreshold);}
else{reset();}});}
return _self;}
init();function reset()
{hide_pagination();opts.scrollContainer.scroll(scroll_handler);call_tooltip();}
function scroll_handler()
{var curScrOffset,scrTreshold;curScrOffset=util.getCurrentScrollOffset(opts.scrollContainer);scrTreshold=get_scroll_treshold();if(curScrOffset>=scrTreshold){if(get_current_page()>=opts.triggerPageTreshold){stop_scroll();show_trigger(function(){paginate(curScrOffset);});}
else{paginate(curScrOffset);}}}
function stop_scroll()
{opts.scrollContainer.unbind('scroll',scroll_handler);}
function hide_pagination()
{$(opts.pagination).hide();}
function get_scroll_treshold(pure)
{var el,treshold;el=$(opts.container).find(opts.item).last();if(el.size()===0){return 0;}
treshold=el.offset().top+ el.height();if(!pure){treshold+=opts.tresholdMargin;}
return treshold;}
function paginate(curScrOffset,onCompleteHandler)
{var urlNextPage;urlNextPage=$(opts.next).attr('href');if(!urlNextPage){if(opts.noneleft){$(opts.container).find(opts.item).last().after(opts.noneleft);}
return stop_scroll();}
if(opts.beforePageChange&&$.isFunction(opts.beforePageChange)){if(opts.beforePageChange(curScrOffset,urlNextPage)===false){return;}}
paging.pushPages(curScrOffset,urlNextPage);stop_scroll();show_loader();loadItems(urlNextPage,function(data,items){var result=opts.onLoadItems.call(this,items),curLastItem;if(result!==false){$(items).hide();curLastItem=$(opts.container).find(opts.item).last();curLastItem.after(items);$(items).fadeIn();}
urlNextPage=$(opts.next,data).attr('href');$(opts.pagination).replaceWith($(opts.pagination,data));remove_loader();hide_pagination();if(urlNextPage){reset();}
else{stop_scroll();}
opts.onRenderComplete.call(this,items);if(onCompleteHandler){onCompleteHandler.call(this);}});}
function loadItems(url,onCompleteHandler,delay)
{var items=[],container,startTime=Date.now(),diffTime,self;delay=delay||opts.loaderDelay;$.get(url,null,function(data){container=$(opts.container,data).eq(0);if(0===container.length){container=$(data).filter(opts.container).eq(0);}
if(container){container.find(opts.item).each(function(){items.push(this);});}
if(onCompleteHandler){self=this;diffTime=Date.now()- startTime;if(diffTime<delay){setTimeout(function(){onCompleteHandler.call(self,data,items);},delay- diffTime);}else{onCompleteHandler.call(self,data,items);}}},'html');}
function paginateToPage(pageNum)
{var curTreshold=get_scroll_treshold(true);if(curTreshold>0){paginate(curTreshold,function(){stop_scroll();if((paging.getCurPageNum(curTreshold)+ 1)<pageNum){paginateToPage(pageNum);$('html,body').animate({'scrollTop':curTreshold},400,'swing');}
else{$('html,body').animate({'scrollTop':curTreshold},1000,'swing');reset();}});}}
function get_current_page()
{var curScrOffset=util.getCurrentScrollOffset(opts.scrollContainer);return paging.getCurPageNum(curScrOffset);}
function get_loader()
{var loader=$('.ias_loader');if(loader.size()===0){loader=$('<div class="ias_loader">'+ opts.loader+'</div>');loader.hide();}
return loader;}
function show_loader()
{var loader=get_loader(),el;if(opts.customLoaderProc!==false){opts.customLoaderProc(loader);}else{el=$(opts.container).find(opts.item).last();el.after(loader);loader.fadeIn();}}
function remove_loader()
{var loader=get_loader();loader.remove();}
function get_trigger(callback)
{var trigger=$('.ias_trigger');if(trigger.size()===0){trigger=$('<div class="ias_trigger"><a href="all.html">'+ opts.trigger+'</a></div>');trigger.hide();}
return trigger;}
function show_trigger(callback)
{var trigger=get_trigger(callback),el;el=$(opts.container).find(opts.item).last();el.after(trigger);trigger.fadeIn();}
function remove_trigger()
{var trigger=get_trigger();trigger.remove();}};$.ias.defaults={container:'#container',scrollContainer:$(window),item:'.item',pagination:'#pagination',next:'.next',noneleft:false,loader:'<img src="images/loader.gif"/>',loaderDelay:600,triggerPageTreshold:4,trigger:'Load more items',tresholdMargin:0,history:true,onPageChange:function(){},beforePageChange:function(){},onLoadItems:function(){},onRenderComplete:function(){},customLoaderProc:false};$.ias.util=function()
{var wndIsLoaded=false;var forceScrollTopIsCompleted=false;var self=this;function init()
{$(window).load(function(){wndIsLoaded=true;});}
init();this.forceScrollTop=function(onCompleteHandler)
{$('html,body').scrollTop(0);if(!forceScrollTopIsCompleted){if(!wndIsLoaded){setTimeout(function(){self.forceScrollTop(onCompleteHandler);},1);}else{onCompleteHandler.call();forceScrollTopIsCompleted=true;}}};this.getCurrentScrollOffset=function(container)
{var scrTop,wndHeight;if(container.get(0)===window){scrTop=container.scrollTop();}else{scrTop=container.offset().top;}
wndHeight=container.height();return scrTop+ wndHeight;};};$.ias.paging=function()
{var pagebreaks=[[0,document.location.toString()]];var changePageHandler=function(){};var lastPageNum=1;var util=new $.ias.util();function init()
{$(window).scroll(scroll_handler);}
init();function scroll_handler()
{var curScrOffset,curPageNum,curPagebreak,scrOffset,urlPage;curScrOffset=util.getCurrentScrollOffset($(window));curPageNum=getCurPageNum(curScrOffset);curPagebreak=getCurPagebreak(curScrOffset);if(lastPageNum!==curPageNum){scrOffset=curPagebreak[0];urlPage=curPagebreak[1];changePageHandler.call({},curPageNum,scrOffset,urlPage);}
lastPageNum=curPageNum;}
function getCurPageNum(scrollOffset)
{for(var i=(pagebreaks.length- 1);i>0;i--){if(scrollOffset>pagebreaks[i][0]){return i+ 1;}}
return 1;}
this.getCurPageNum=function(scrollOffset)
{scrollOffset=scrollOffset||util.getCurrentScrollOffset($(window));return getCurPageNum(scrollOffset);};function getCurPagebreak(scrollOffset)
{for(var i=(pagebreaks.length- 1);i>=0;i--){if(scrollOffset>pagebreaks[i][0]){return pagebreaks[i];}}
return null;}
this.onChangePage=function(fn)
{changePageHandler=fn;};this.pushPages=function(scrollOffset,urlNextPage)
{pagebreaks.push([scrollOffset,urlNextPage]);};};$.ias.history=function()
{var isPushed=false;var isHtml5=false;function init()
{isHtml5=!!(window.history&&history.pushState&&history.replaceState);isHtml5=false;}
init();this.setPage=function(pageNum,pageUrl)
{this.updateState({page:pageNum},'',pageUrl);};this.havePage=function()
{return(this.getState()!==false);};this.getPage=function()
{var stateObj;if(this.havePage()){stateObj=this.getState();return stateObj.page;}
return 1;};this.getState=function()
{var haveState,stateObj,pageNum;if(isHtml5){stateObj=history.state;if(stateObj&&stateObj.ias){return stateObj.ias;}}
else{}
return false;};this.updateState=function(stateObj,title,url)
{if(isPushed){this.replaceState(stateObj,title,url);}
else{this.pushState(stateObj,title,url);}};this.pushState=function(stateObj,title,url)
{var hash;if(isHtml5){history.pushState({ias:stateObj},title,url);}
else{}
isPushed=true;};this.replaceState=function(stateObj,title,url)
{if(isHtml5){history.replaceState({ias:stateObj},title,url);}
else{this.pushState(stateObj,title,url);}};};})(jQuery);

我已经为此工作了两天,但无法修复它,因为我对编码一无所知。我只能进行实验,删除一些代码等,但我认为解决方案不止于此。

任何帮助将不胜感激。

4

3 回答 3

8

danemacmillan,你是对的。我添加了以下代码,现在 tooltipster 也适用于动态生成的内容。

<script type="text/javascript">
    $('body').on('mouseover mouseenter', '.tooltip', function(){
         $(this).tooltipster({
            contentAsHTML: 'true',
            animation: 'grow',
            theme: '.my-custom-theme',
            position: 'top-left'
         });
         $(this).tooltipster('show');
    });
</script>

我仍然不相信它,但它确实有效!:D

于 2014-08-05T12:42:22.303 回答
7

您遇到的问题至少可以通过两种方式解决。最好的解决方案是减少编写所需的代码量,甚至可以提高应用程序的性能和可维护性。

这是一个会咬你一次的问题,但很少会再次出现。对于 JavaScript 新手来说这很常见,所以请记住这一点。

Tooltipster 在文档“准备就绪”时触发。当文档完全构建并准备好使其节点成为目标时,它就已准备就绪 [1]。问问自己,“文件多久准备一次?” 答案当然是每页刷新一次。如果文档每次页面刷新只能准备一次,这意味着附加到事件的匿名函数(作为页面重新刷新,或“准备好”)只会被触发一次。匿名 tooltipster 函数只会被触发一次,所有已知和当前可用的匹配节点。工具提示器不知道在文档准备好后添加到文档中的节点。

知道了这一点,至少可以从几个角度来解决这个问题:

  1. 每次对文档进行更改时,都会触发匿名工具提示功能。文档部分中附加了工具提示器功能的所有节点很可能已经被删除,因为重新排列文档中的节点往往是破坏性的,除非小心。这种方法还可以,但远非理想,当然也不是高性能或最可维护的。

  2. 让父节点将事件触发委托给其子节点。这是应该做的。这意味着父级将侦听以前每个单独的子级会执行的事件。父母可能永远不会改变或被操纵,但它的内容(孩子)会。附加到父节点是一种更健壮和可维护的方法;此外,它在浏览器中的执行速度要快得多,这意味着最终用户会喜欢更快的实现。附加到父节点的单个事件可以处理发生在子节点上的所有事情。

jQuery 使事件委托变得非常简单。再说一次,普通的旧 JavaScript 也是如此。不过,您使用的是前者。阅读有关 jQuery 的事件委托。在您阅读之前不要替换您网站上的代码。这大概就是需要写的内容了;它尚未经过测试,因此可能需要进行调整:

$(document).ready(function() {
    $('#sortable-game-box-list').on('mouseover mouseout', '.tooltip', function(e) {
        $(e.target).tooltipster({
            position: 'bottom-left',
            contentAsHTML: 'true',
            animation: 'grow',
            theme: '.my-custom-theme'
        });
    });
});

如前所述,记住这一点。这将是 JavaScript 开发中经常遇到的问题,至少在经验占主导地位之前是这样。


[1] 顺便说一句,这与加载文档时不同,这意味着除了所有节点都处于活动状态之外,还加载了文档拉入的所有资产;资产是外部脚本、图像以及同步拉入的任何其他内容。

于 2014-08-04T15:28:33.433 回答
0

为我工作。对我来说,我不需要在鼠标悬停、鼠标离开时创建事件......

<script type="text/javascript">
   $('.tooltip1')
    .tooltipster({
        ....some options
   })           
   .tooltipster('content', 'some result from api'); 
</script>
于 2020-02-25T09:42:26.860 回答