点击商品评价 就定位到下面了

今天在项目中碰到一个需求,就是在input输入框中录入数据时(名字),假如敲入了一部分,在数据库中存在已有的姓名的前缀与之匹配,就弹出一个 google页面那种效果的下拉框,把相关的姓名列出来供他选择。可以用箭头上下选择,也可以用鼠标选择。这样可以提高录入的效率。

    输入框的布局如下:

   

  最终的效果如下:

 

 

  表单中输入框的html代码为:

<tr><td>发件人</td><td><input type="text" name="sendername" id="sendername" value=""/></td></tr>

 

为了在输入一些内容时,能够显示出那个选择框,我们要建立一个div,初始时不可见,当需要时就显示出来,并且将它移动到正确的位置。这个div采用的定位为绝对定位,这样就可以在整个页面用lefttop来定位了,z-index99,这样就可以盖住下面的东西。选择框的div:

<div id="helper" class="gac_m" style="visibility:hidden;" width="100%">

</div>

 gac_mcss定义为:

.gac_m {
background
:white none repeat scroll 0 0;
border
:1px solid black;
cursor
:default;
font-size
:13px;
line-height
:17px;
margin
:0;
position
:absolute;
z-index
:99;
width
:100px;
left
:10px;
top
:10px;
}

 当需要显示时,我们需要将idhelperdiv移动到正确的位置,这个位置就是input输入框的正下方,left即为input的相对页面左边的位移,top即为input相对页面上边的位移加上input本身的高度。现在的问题是怎么取得一个元素的相对页面的绝对位置,这个可以通过offsetparent取的父亲结点递归的来算。下面函数getabsposition用来取得元素obj的绝对位置,gettable(obj)用来把idhelperdiv定位到obj正下方:

function getabsposition(obj) {
    
var r = {
        left: obj.offsetleft,
        top : obj.offsettop
    };
    r.left = obj.offsetleft;
    r.top  = obj.offsettop;
    
if(obj.offsetparent) {
        
var tmp = getabsposition(obj.offsetparent);
        r.left += tmp.left;
        r.top  += tmp.top;
    }
    
return r;
  }
  
function gettable(obj) {
    
var pos = getabsposition(obj);
    pos.top += obj.offsetheight;
    document.getelementbyid('helper').style.top = pos.top + "px";
    document.getelementbyid('helper').style.left = pos.left + "px";
    document.getelementbyid('helper').style.width = obj.offsetwidth + "px";
    document.getelementbyid('helper').style.visibility = '';
  }

现在可以定位并且显示idhelperdiv了,下面的问题是当输入框中的内容改变时,采用ajax去服务器取得数据,然后更新div中的内容,并且显示出来。那么怎么侦测输入框中的内容改变了呢?假如采用onchange事件,只有当输入框失去焦点时才会触发,所以我们只有采用定时器的方式了,每隔一个时间片检查一下输入框的值,假如值改变了,就执行更新过程。下面checkvalue函数就是用来给定时器的函数,用来检查输入框的内容是否改变,getnameresponseajax的回调函数,用来对服务器传回的json数据解码并且以一定的方式显示在div中。

function checkvalue() {
    
var nowvalue = document.getelementbyid('sendername').value;
    
if(prevalue != nowvalue) {
        ajax.call('useradv.php?act=getsendername&name='+nowvalue,'',getnameresponse, 'get', 'json');
    }
    prevalue = nowvalue;
    settimeout(checkvalue,100);
  }

function getnameresponse(result) {
    
var info = result.content;

  var html = '<table width="100%">';

for(var i = 0;i < info.length; i++) {

        html += '<tr id="tr' + (i+1) +'" οnmοuseοver="choosetr(' + (i+1) +');" οnclick="selecttr();">'
               + '<td colspan="2">' + info[i].sendername + '</td></tr>';

    }

    html += '<td align="left"><font color="red">按空格键选择</font></td>'
           +'<td align="right"><a href="#" οnclick="document.getelementbyid(/'helper/').style.visibility=/'hidden/';">'+
           '
关闭</a></td></tr></table>';
   

document.getelementbyid('helper').innerhtml = html;
    
if(info.length > 0) {
        gettable(document.getelementbyid('sendername'));
    }
else{
        document.getelementbyid('helper').style.visibility ='hidden';
    }

 }

其中trclassnamegca_b表示该行被选中,其css定义为:

.gac_b {

background:#3366cc !important; color:white;

}

 

下面需要解决的问题是用向上和向下的按键来在选择框中选择,这样就需要检测键盘按键了,可以直接通过document.onkeydown来注册按键检测函数,当按下向上和向下的键时,就上下移动选中的行,函数choosetr(nextid)用来选择第nextid行,当然需要记录nowid为前面选中的行,然后selecttr()是当按了空格键或者用鼠标点击了后模拟选中的动作,用选中的值来填充input

var nowid = 0;
function selecttr() {
    
try
    {
        
if(document.getelementbyid('helper').style.visibility == 'hidden') return;
        document.getelementbyid('sendername').value = 
document.getelementbyid('tr'+nowid).cells[0].innerhtml;
        settimeout(
function(){

                        document.getelementbyid('sendername').value

                        =utils.trim(document.getelementbyid('sendername').value);},50);      

        falg = false;

        nowid = 0;
        
var eles = document.getelementsbyname('trname');
        
for(var i = 0; i < eles.length; i++) {
            eles[i].classname = '';
        }

        document.getelementbyid('helper').style.visibility ='hidden';

    }

catch (e)

    {

    }

  }

document.onkeydown = function(e) {    

 var keycode;

try

    {

        keycode = event.keycode;

    }

    catch (err)

    {

        keycode = e.keycode;

    }

    if(keycode == 40) {

        //按了向下的键

        choosetr(nowid+1);

    } else if(keycode == 38) {

        //按了向上的键
        choosetr(nowid-1);

    } else if(keycode == 32) {

        selecttr();

    }

}

 function choosetr(nextid) {

     var len = 0;

     do

     {

        try

        {

            var obj = document.getelementbyid('tr'+(len+1));

   if(obj) len++; else break;

}

   catch (e)

   {

     break;

        }

     }while(1);

  if(nextid > len) nextid = 1;
     
if(nextid < 1) nextid = len;
     
if(nowid >=1 && nowid <= len) {
         document.getelementbyid('tr' + nowid).classname = '';
     }

     document.getelementbyid('tr' + nextid).classname = 'gac_b';

     nowid = nextid;

  }

  settimeout(checkvalue,100);

 这样就可以了,最后需要注重的是有个小问题:浏览器自带的自动历史选择下拉框会与我们做的冲突,解决方法就是设置inputoncomplete="off"

最后贴一下服务器端的php程序:

elseif ($action == 'getsendername') {
    
$name = trim($_get['name']);
    
$rows = array();
    
if(strlen($name) > 0) {
        
$sql = "select distinct sendername from ".$globals['ecs']->table('useradv').
               " where sendername like '
$name%' and sendername != '$name' limit 0,10";
        
$rows = $globals['db']->getall($sql);
    }
    
include_once(root_path . 'includes/cls_json.php');
    
$json = new json();
    
$result = array('error'=>0, 'message'=>'', 'content'=>'');
    
$result['content'] = $rows;
    
die($json->encode($result));
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值