我正在尝试创建类似于iPhone键盘的行为(参见附图)。在用户启动和移动触摸时,她会看到触摸的元素的缩放版本,并且在触摸时会发生选择。我正在使用Zepto。
我可以正确获取触摸坐标,但无法找到手指下方的物体。我正在使用下面的代码来检查返回哪个元素作为事件的目标。
$("#myList li").live('touchmove', function(event) {
console.log(event.touches[0].target.innerHTML);
});
这将始终返回starttouch上的事件。
在Apple documentation上触摸应该有 event.touches event.changedTouches event.targetTouches
我已经尝试检查每个对象上的第一个元素,但它们似乎都只包含starttouch-element作为目标。这里有什么我想念的吗?
我从
正确获取了触摸的坐标var positionTop = event.touches[0].pageY;
var positionLeft = event.touches[0].pageX;
如果一切都失败了,我开始想到也许有办法在坐标下找到DOM元素。
任何想法都表示赞赏。
答案 0 :(得分:3)
触摸事件下的对象由event.target
给出。此外,您应该绑定到touchstart
和touchend
个事件。看到我做的这个例子:
http://ampersand.no.de/iOSkeyboard.html
源代码:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<style>
body{
font-family:arial;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;
}
.entry{
border:1px solid green;
color:darkGreen;
margin:25px;
font-size:25px;
font-family:verdana, arial,"sans serif";
padding:10px;
width:500px;
word-wrap:break-word;
}
.wrapper{
height:200px;
position:relative;
margin:25px;
}
.keyboard{
position:absolute;
bottom:0;
}
.key{
border:1px solid darkGray;
display:inline-block;
text-align:center;
cursor:pointer;
margin-top:1px;
border-radius: 4px;
font-family:arial,"sans serif";
width:30px;
height:30px;
line-height:30px;
}
.shift{
width:60px;
margin-left:35px;
}
.spacebar{
width:126px;
}
.backspace{
width:60px;
}
.keypress{
border:1px solid blue;
}
#floatKey{
border-bottom-left-radius:10px;
border-bottom-right-radius:10px;
border-bottom:0px;
border-color:blue;
font-weight:bold;
font-size:24px;
cursor:pointer;
width:40px;
height:40px;
line-height:40px;
background-color:white;
-moz-box-shadow: -5px 0px 5px #ccc;
-webkit-box-shadow: -5px 0px 5px #ccc;
box-shadow: -5px 0px 5px #ccc;
}
.touchStart{
border-color:blue;
border-top:0px;
border-top-left-radius:0px;
border-top-right-radius:0px;
-moz-box-shadow: -5px 5px 5px #ccc;
-webkit-box-shadow: -5px 5px 5px #ccc;
box-shadow: -5px 5px 5px #ccc;
}
</style>
</head>
<body>
<h3>iOS-style keyboard examples</h3>
<div class="entry">|</div>
<div class="wrapper">
<div>With mouse events:</div>
<div class="keyboard" id="mousekb">
<div class="row">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
<span>0</span>
</div>
<div class="row">
<span>q</span>
<span>w</span>
<span>e</span>
<span>r</span>
<span>t</span>
<span>y</span>
<span>u</span>
<span>i</span>
<span>o</span>
<span>p</span>
</div>
<div class="row" style="margin-left:18px">
<span>a</span>
<span>s</span>
<span>d</span>
<span>f</span>
<span>g</span>
<span>h</span>
<span>j</span>
<span>k</span>
<span>l</span>
</div>
<div class="row">
<span>z</span>
<span>x</span>
<span>c</span>
<span>v</span>
<span>b</span>
<span>n</span>
<span>m</span>
<span>,</span>
<span>.</span>
</div>
<div class="row">
<span class="shift">shift</span>
<span class="spacebar"> </span>
<span class="backspace">⇐</span>
</div>
</div>
</div>
<div class="entry">|</div>
<div class="wrapper">
<div>With touch events (zoom in for better view):</div>
<div class="keyboard" id="touchkb">
<div class="row">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
<span>0</span>
</div>
<div class="row">
<span>q</span>
<span>w</span>
<span>e</span>
<span>r</span>
<span>t</span>
<span>y</span>
<span>u</span>
<span>i</span>
<span>o</span>
<span>p</span>
</div>
<div class="row" style="margin-left:18px">
<span>a</span>
<span>s</span>
<span>d</span>
<span>f</span>
<span>g</span>
<span>h</span>
<span>j</span>
<span>k</span>
<span>l</span>
</div>
<div class="row">
<span>z</span>
<span>x</span>
<span>c</span>
<span>v</span>
<span>b</span>
<span>n</span>
<span>m</span>
<span>,</span>
<span>.</span>
</div>
<div class="row">
<span class="shift">shift</span>
<span class="spacebar"> </span>
<span class="backspace">⇐</span>
</div>
</div>
</div>
<div id="floatKey" class="key" style="display:none"></div>
<script>
SHIFT=false;
$('.keyboard span').addClass('key');
function touchStart(ev){
ev.preventDefault();
var o=$(ev.target).offset();
$('#floatKey').html($(ev.target).html())
.show()
.offset({top:(o.top-$('#floatKey').outerHeight()), left:(o.left-5)});
$(ev.target).addClass('touchStart');
}
function touchEnd(ev){
ev.preventDefault();
$('#floatKey').hide();
$(ev.target).removeClass('touchStart');
}
function keyrelease(ev){
ev.preventDefault();
outlineKey(ev.target);
$(ev.target).removeClass('keydown');
$('#floatKey').removeClass('keydown');
var text=$('.entry').eq(0).text();
$('.entry').text(text.substr(0,text.length-1)+$(ev.target).text()+'|');
}
function shiftKey(ev){
ev.preventDefault();
if(SHIFT){
$('.keyboard span').not('.shift').each(function(idx,el){
$(el).text($(el).text().toLowerCase());
})
$(ev.target).removeClass('keypress');
SHIFT=false;
}else{
$('.keyboard span').not('.shift').each(function(idx,el){
$(el).text($(el).text().toUpperCase());
})
$(ev.target).addClass('keypress');
SHIFT=true;
}
}
function outlineKey(el){
$(el).addClass('keypress');
setTimeout(function(){
$(el).removeClass('keypress')
},500);
}
function backspace(ev){
ev.preventDefault();
outlineKey(ev.target);
var text=$('.entry').eq(0).text();
$('.entry').text(text.substr(0,text.length-2)+'|');
}
//mouse keyboard
$('#mousekb span').not('.spacebar,.shift,.backspace').bind('mouseenter',touchStart);
$('#mousekb span').not('.spacebar,.shift,.backspace').bind('mouseout',touchEnd)
$('#mousekb span').not('.shift,.backspace').bind('mouseup',keyrelease)
$('#mousekb .shift').bind('mouseup',shiftKey);
$('#mousekb .backspace').bind('mouseup',backspace);
//touch keyboard:
$('#touchkb span').not('.spacebar,.shift,.backspace').bind('touchstart',touchStart);
$('#touchkb span').not('.spacebar,.shift,.backspace').bind('touchend',touchEnd);
$('#touchkb span').not('.shift,.backspace').bind('touchend',keyrelease)
$('#touchkb .shift').bind('touchend',shiftKey);
$('#touchkb .backspace').bind('touchend',backspace);
</script>
</body>
<强>更新强>
好的,我找到了它,'它'被称为document.getElementFromPoint()
。 Mozilla的网站上有一些文档(https://developer.mozilla.org/En/DOM/Document.elementFromPoint)。它将获得给定顶部和左侧坐标的元素。这可以很容易地用于跟踪手指当前在哪个键上。我已经更新了我的代码示例以使用这个很棒的函数。以下是一些更新的函数,它们可以获取当前的触摸元素并更新“悬停键”:
//functions for touchmove implementation:
function getElAtTouchPosition(ev){
var touch = ev.originalEvent.touches[0] || ev.originalEvent.changedTouches[0] || ev.touches[0];
var top = touch.pageY;
var left = touch.pageX;
var el=document.elementFromPoint(left,top);
if(el.className=='key'){
return el;
}else{
return null;
}
}
function move(ev){
ev.stopImmediatePropagation();
var el=getElAtTouchPosition(ev);
if(el.className=='key' && el!=currentHoverKey){
updateFloatKey(el);
currentHoverKey=el;
}
}
function updateFloatKey(el){
var o=$(el).offset();
$(currentHoverKey).removeClass('touchStart');
$('#floatKey').html($(el).html())
.show()
.offset({top:(o.top-$('#floatKey').outerHeight()), left:(o.left-5)});
$(el).addClass('touchStart');
}
function touchStart2(ev){
ev.preventDefault();
updateFloatKey(ev.target);
currentHoverKey=ev.target;
}
function touchStop2(ev){
$(currentHoverKey).removeClass('touchStart');
$('#floatKey').hide();
}
Check out the example了解所有这些是如何使用的。我已经在iPad 2(iOS 4.3)上测试了它,它可以工作。它还需要进行一些调整以提高平滑度,并考虑到touchmove最终出现在非关键元素上的情况。我有兴趣看看它在Android上是如何工作的。我还没有完成第三个键盘的文本输入代码,但是你可以结合我之前的一些代码来使它工作。祝你好运。
注意:阻止touchmove事件传播/冒泡DOM树是非常重要的。如果它确实传播,那么它将变成滚动,并且在iOS设备上滚动时 DOM操作被禁用,因此您将无法更新“悬停键”。当touchmove事件触发非关键元素时,您需要考虑所有边缘情况。