一个气泡提示的Javascript控件

某日,忽的想写个js小控件。功能很简单,就是可以在文本框下面显示一个气泡提示,如上图。图是Chrome里截来的,是Chrome原生的提示样式。只要在文本框启用『required』,提交时内容为空时就会出现如图提示。

首先第一步,该是要构建一个提示文字的HTML模型,那么弹出提示时就可以被重复构建了(如上图)。

<div class="megbox">
    <div class="megbox_top"></div>
    <div class="megbox_meg">
        <div class="megbox_txt">提示文字..</div>
    </div>
</div>

HTML模型包含两个部分,提示文字和一个啥也没有是div,那个div就是用来显示提示消息上方的小三角的~因此,我们还需要一些CSS来定义赋予样式。

.megbox{
    position: absolute;
    background-color: #FFF;
    border: 1px solid #a4acb5;
    padding: 5px 10px;
    border-radius: 5px;
    z-index: 100;
}
.megbox_top{
    width: 13px;
    height: 7px;
    position: absolute;
    background: url(./images/up.gif) no-repeat;
    top: -7px;
}
.megbox_meg{
    padding-left: 25px;
    background: url(./images/warning.gif) no-repeat;
    line-height: 20px;
}
.megbox_txt{}/* 暂且保留,说不定以后加点什么样式~~ */

CSS一共需要调用到两张背景图: 

因为气泡提示基本上是悬浮在文本框上方的,所以不会被计入正常流中,因此通过「position: absolute」属性使其脱离正常流。

接下来就是Javascript的部分了。因为本人大学学的是C++,所以对面向对象比较钟情,所以就用面向对的方法来开发这个js控件。

首先,定义一下我们需要那些属性和方法:

属性:

element:气泡指向的文本框元素,姑且称之为目标元素吧~;

message:消息提示的内容;

id:说不定我们需要弹出好多个提示框,所以我们需要一个唯一标识来区隔它们~;

方法:

Show:显示气泡提示;

Remove:移除气泡;

OK,首先写个构造函数,这个类就叫MessageBox吧~

MessageBox = function(element, id, message)
{
    // Init value
    this.message = "";
    this.element = undefined;
    this.id = "";

    this.message = message;
    this.element = element;
    this.id = id;
};

接着就是完成两个方法了~

Show——首先要解决两个问题:

插入DOM元素;

显示在哪儿?

第一个问题好解决,查一查W3School就O了~

第二个,因为我们是用绝对定位,而且是要显示在目标元素附近。因此就需要知道目标元素的位置。这个嘛…就要Google一下了。

我参照了这位大牛的函数——阮一峰

略做修改后,如下:

document.getElementView = function (element)
{
    if(element != document)
        return {
            width: element.offsetWidth,
            height: element.offsetHeight
        }
    if (document.compatMode == "BackCompat"){
        return {
            width: document.body.clientWidth,
            height: document.body.clientHeight
        }
    } else {
        return {
            width: document.documentElement.clientWidth,
            height: document.documentElement.clientHeight
        }
    }
};

document.getElementLeft = function (element)
{
    var actualLeft = element.offsetLeft;
    var current = element.offsetParent;
    while (current !== null){
        actualLeft += current.offsetLeft;
        current = current.offsetParent;
    }
    return actualLeft;
};

document.getElementTop = function (element)
{
    var actualTop = element.offsetTop;
    var current = element.offsetParent;
    while (current !== null){
        actualTop += current.offsetTop;
        current = current.offsetParent;
    }
    return actualTop;
};

把他们都作为document方法加进入了~这样似乎不太好,最安全的做法应该是作为MessageBox的私有方法。不过个人喜欢啦~

Remove的话就是把创建的元素删除而已~

最后方法定义如下:

MessageBox.prototype = {

    constructor : MessageBox, // 声明构造函数

    Show : function()
    {
        if(!this.element) return false;
        if(this.element.box)
            this.element.box.Remove(true);
        var megbox = document.createElement("div");
        megbox.className = "megbox";
        megbox.id = "megbox_" + this.id;    //把id加上前缀,作为气泡的id
        var megbox_top = document.createElement("div");
        megbox_top.className = "megbox_top";
        var megbox_meg = document.createElement("div");
        megbox_meg.className = "megbox_meg";
        var megbox_txt = document.createElement("div");
        megbox_txt.className = "megbox_txt";
        var megs=document.createTextNode(this.message);

        megbox.appendChild(megbox_top);
        megbox.appendChild(megbox_meg);
        megbox_meg.appendChild(megbox_txt);
        megbox_txt.appendChild(megs);
        this.element.box = this;

        document.getElementsByTagName("body")[0].appendChild(megbox);

        var node_view = document.getElementView(this.element);
        var node_top = document.getElementTop(this.element);
        var node_left = document.getElementLeft(this.element);

        megbox.style.top = (node_top + node_view.height + 5) + "px";
        megbox.style.left = node_left + "px";

        return true;
    },

    Remove : function()
    {
        var id = this.id;
        var node = document.getElementById("megbox_" + id);
        if(node)
        {
            node.parentNode.removeChild(node);
            return true;
        }
        return false;
    }
};

因为提示框显示在目标元素下方,因此提示框绝对定位的

top = nodetop + nodeview.height + 5 ;(如下图)

加上5px是为了避免提示框贴在文本框底部。

如此,气泡提示控件就完成了,调用时如下:

var test = document.getElementById("test");
var Box = new MessageBox(test, 1, "Test Message..");
Box.Show(); // Show the MessageBox

// -----------------------------------

if(Box instanceof MessageBox) Box.Remove(); // Remove MessageBox

最后,附上增强版MessageBox——下载地址??

原文地址:https://www.cnblogs.com/jlfw/p/12684965.html

时间: 2024-08-02 07:30:53

一个气泡提示的Javascript控件的相关文章

QTP回放时弹出 提示:一个或多个ActiveX控件无法显示

今天在录系统的脚本,回放时遇到以下的问题: 在QTP中弹出消息框,一个或多个ActiveX控件无法显示,如下图: 在Tools-->Options-->Active screen-->Advanced里把"Load ActiveX",即可解决你的问题. QTP回放时弹出 提示:一个或多个ActiveX控件无法显示

javascript控件开发之工具栏控件

在前几篇的基础上,本篇将开发工具栏控件,工具栏控件一般包括三部份, 1.toolBar控件,简单说就是工具栏容器, 2.toolButton控件,即工具栏上的按钮控件,该按钮控件包括图标和文字两部份, 3.则是分隔符控件,一般分隔符控件也是在toolButton控件基础上引申出来的, 为了简单易学,我们这里直接用上一篇的控件作为toolBar控件使用,也就是我们这次编写出来的toolButton控件直按放一Panel控件上, 首先在component\ui\文件夹下添加控件文件,com.ui.t

Win10系列:JavaScript 控件的使用

向页面中添加的控件可分为两种类型:标准的HTML控件和WinJS库控件.其中标准的HTML控件是指HTML标准中定义的基本控件,如按钮和复选框:WinJS库控件是为开发基于JavaScript 的Windows应用商店应用提供的新控件,如ListView.HtmlControl和PageControl等.下面首先介绍如何添加这两种类型的控件,然后介绍如何为控件注册事件处理函数和设计控件的样式. (1)添加标准的HTML控件 向页面中添加标准的HTML控件可以通过定义相应的HTML元素来实现.例如

QTP录制后弹出框一个或多个ActiveX控件无法显示的解决方法

制一段脚本代码,在专家视图窗口中编辑录制的脚本代码时,会碰到弹出一个对话窗口,提示为"当前安全设置禁止运行该页中的ActiveX 控件,因此,该页可能无法正常显示"类似的东西,而在人工操作时却没有这样的现象.(如图) 问题主要出在于QTP设置本身,之所以在编辑录制好的脚本时,QTP出现关于Active的对话提示窗口,问题在于QTP的设置,要消除该提示窗口.应对QTP作如下设置:toos–options–Active Screen–Advanced–点选Load ActiveX cont

C#在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级

首先在form1的窗体载入中新建了一个Class1对象并将本身的引用传递进入其构造函数,然后在Class1的构造函数中创建一个线程.该线程所代理的方法事件是本类中的一个add方法.而add方法的内容则是在form1上放一个textbox.然而这个流程你需要注意的有几个问题:1.哪个是主线程?所谓主线程是第一个启动的线程,是从main开始的.form1的这个窗体是由主线程创建的.2.Thread t的线程是什么?t是由主线程创建的,t的操作内容是在由主线程创建的窗体上放一个textbox.也就是说

一个Activity掌握Design新控件

一个Activity掌握Design新控件 欢迎转载,转载请注明原文地址:http://blog.csdn.net/lavor_zl/article/details/51295364谢谢. 谷歌在推出Android5.0的同时推出了全新的设计Material Design,谷歌为了给我们提供更加规范的MD设计风格的控件,在2015年IO大会上推出了Design支持包,Design常用的新控件有下面8种. 1. TextInputLayout(文本输入布局) TextInputLayout的作用是

创建一个带模版的用户控件 V.3

再重构此篇<创建一个带模版的用户控件  V.2>http://www.cnblogs.com/insus/p/4164149.html 让其它动态实现header,Item和Footer. Insus.NET不想所有代码写在InstantiateIn(Control container)方法内的switch分流上.其实是想使用开发设计模式的中介者(Mediator)来拆分它. 拆分为四个方法:ListItemType.Header: ListItemType.Item: ListItemTyp

创建一个带模版的用户控件 V.2

前面有做练习<创建一个带模版的用户控件>http://www.cnblogs.com/insus/p/4161544.html .过于简化.通常使用数据控件Repeater会有网页写好Header,Item,AlternatingItem和Footer.如果需要动态产生列时,我们需要在后台写好模板. 再来复习一下这篇<Repeater控件动态变更列(Header,Item和Foot)信息>http://www.cnblogs.com/insus/archive/2013/03/22

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.android实现自绘日期选择控件 目的: 通过一个相对复杂的自定义自绘控件来分享: 1.ios以及android自定义自绘控件的开发流程 2.objc与c/c++混合编程 3.android ndk的环境配置,android studio ndk的编译模式,swig在android ndk开发中的作