【问题标题】:Dijit custom Tooltip not workingDijit 自定义工具提示不起作用
【发布时间】:2014-04-15 07:04:42
【问题描述】:

我正在将 Web 应用程序从 Dojo 1.3.1 迁移到 Dojo 1.9.3。该应用程序有很多自定义小部件。其中之一是HelpTip,它是从dijit/Tooltip 扩展而来的。

现在,当我单击显示帮助提示的按钮时,在下面显示的第 2 行出现异常,显示为TypeError: this._showTimer.remove is not a function

if(this._showTimer){
    this._showTimer.remove();
    delete this._showTimer;
}

我从 dijit/Tooltip (Dojo 1.9.1) 的 open 函数中复制了上面的代码。但 dijit.Tooltip (Dojo 1.3.1) 有所不同,如下所示:

if(this._showTimer){
    clearTimeout(this._showTimer);
    delete this._showTimer;
}

当我调试应用程序时,它会在_showTimer 变量中显示一些编号值。因此,您可以看到在 1.3.1 版本的应用程序中,clearTimeout 获得了一个数字并且它工作正常。但在 1.9.3 版本中,它试图调用编号值的 remove 方法,我真的不知道这是为了什么。

编辑:
这是我的HelpTip.js 文件的代码

    define([
    "dojo/_base/array",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/dom",
    "dojo/has",
    "dojo/topic",
    "dijit/Tooltip",
    "dojo/on"
], function (array, declare, lang, dom, has, topic, Tooltip, on) {

    var HelpTip = declare("tt.widget.HelpTip",Tooltip,{
            // summary
            //      Pops up a tooltip (a help message) when you hover over a node.

            showDelay: 0,
            _noHelpAvailable: "Unable to load help for this item. Please contact support.",
            api: null,

            connectHandlers: function(/*Array*/ ids) {
                array.forEach(ids, function(id) {
                    var node = dom.byId(id);
                    if (node && node.tagName.toLowerCase() != "html" && node.tagName.toLowerCase() != "head" && node.tagName.toLowerCase() != "body") {
                        this.connectId.push(node);
                        // For A11y we may need to work with onFocus as well

                            this.connect(node, "onclick", "_onClick");


                        if(has("ie")){
                            // BiDi workaround
                            node.style.zoom = 1;
                        }
                    }
                }, this);

            },

            disconnectHandlers: function(/*Array*/ ids) {

                if (ids) {
                    for (var i = this._connects.length - 1; i >= 0; i--) {
                        if (this._connects[i] && this._connects[i][0] && this._connects[i][0][0]) {
                            if (array.indexOf(ids, this._connects[i][0][0].id) != -1) {
                                this._connects[i].remove();
                            }
                        }
                    }
                }
            },

            _onClick: function(/*Event*/ e) {
                e.preventDefault(); // don't navigate!
                this._onHover(/*Event*/ e);
            },

            _onHover: function(/*Event*/ e){

                if (e.target.id == null || e.target.id == "") {
                    this.label = this._noHelpAvailable;
                } else {
                    this.label = "Retreiving help for this item...";
                    this.aroundNode = e.target;
                    var ids = e.target.id.split("_");
                    this.api.helpGetText(lang.hitch(this, this.helpGetText), ids[0], ids[1], ids[2]);
                }

                if(!this._showTimer){
                    var target = e.target;
                    this._showTimer = setTimeout(lang.hitch(this, function(){this.open(target)}), this.showDelay);
                }

            },

            _onUnHover: function(/*Event*/ e){
                // keep a tooltip open if the associated element has focus
                if(this._focus){ return; }
                if(this._showTimer){
                    clearTimeout(this._showTimer);
                    delete this._showTimer;
                }
                this.closeNodeConnect.remove();
                this.close();
            },

            helpGetText: function(/*String*/ helpText, /*Object*/ error) {

                if (error) {
                    topic.publish("/errorHandling/trapError", error);
                    return;
                }

                this.closeNode = document.createElement("div");
                this.closeNode.className = "fakeLink";
                this.closeNode.innerHTML = "Close";
                this.closeNodeConnect = this.connect(this.closeNode, "click", "_onUnHover");

                if (helpText != null && helpText != "") {
                    if (dijit._masterTT.containerNode != null) {
                        dijit._masterTT.containerNode.innerHTML = helpText + "<br><br>";
                        dijit._masterTT.containerNode.appendChild(this.closeNode);
                    }

                } else {
                    if (dijit._masterTT.containerNode != null) {
                        dijit._masterTT.containerNode.innerHTML = this._noHelpAvailable + "<br><br>";
                        dijit._masterTT.containerNode.appendChild(this.closeNode);
                    }
                }

                // Firefox bug. when innerHTML changes to be shorter than previous
                // one, the node size will not be updated until it moves.
                dijit._masterTT.domNode.style.top = (dijit._masterTT.domNode.offsetTop + 1) + "px";

                // position the element and change CSS according to position
                var align = dijit._masterTT.isLeftToRight() ? {'BR': 'BL', 'BL': 'BR'} : {'BL': 'BR', 'BR': 'BL'};
                var pos = dijit.placeOnScreenAroundElement(dijit._masterTT.domNode, this.aroundNode, align);
                this.aroundNode = null;
                dijit._masterTT.domNode.className="dijitTooltip dijitTooltip" + (pos.corner=='BL' ? "Right" : "Left");//FIXME: might overwrite class

            }


        }
    );
    return HelpTip;
});

谢谢

【问题讨论】:

  • 您能否发布您用于创建HelpTip 的代码,或者您的HelpTip 本身的代码?当您单步执行代码时,最好知道_showTimer 的值是什么。
  • 调试器显示_showTime=417
  • 你能发布HelpTip的代码,以及你用来调用/创建它的代码吗?
  • 我已经更新了问题并粘贴了HelpTip.js文件的代码。

标签: javascript dojo tooltip


【解决方案1】:

在 Dojo 1.9 中 this._showTimer 是一个函数,但您的代码将其替换为 setTimeout 句柄。 if 应该返回的函数在_WidgetBase (this.defer) 中定义。在 Tooltip 的源代码中可以看到这段代码:

        _onHover: function(/*DomNode*/ target){
        // summary:
        //      Despite the name of this method, it actually handles both hover and focus
        //      events on the target node, setting a timer to show the tooltip.
        // tags:
        //      private
        if(!this._showTimer){
            this._showTimer = this.defer(function(){ this.open(target); }, this.showDelay);
        }
    },

这意味着 this._showTimer 连接到 _widgetBase 中定义的函数。该函数是围绕 setTimeout 的某种包装函数,以防止在小部件已被销毁时发生事件。我建议使用 this.inherited(arguments) 并使用小部件的内置计时功能。

【讨论】:

    猜你喜欢
    • 2020-12-10
    • 2020-09-23
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    相关资源
    最近更新 更多