检测单击元素的内部文本而不将文本包装在第二个元素中

use*_*522 3 html javascript jquery

我有一个Div,它使用CSS我的页面的一半大:

<div id="bigdiv">
     CLICK ON THIS TEXT
</div>
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个javascript或jquery代码来检测单击文本而不是元素的其余部分.有没有办法做到这一点?

Sam*_*son 8

由于我们无法直接在textNodes上监听事件,因此我们必须采取更具创造性的途径来解决问题.我们可以做的一件事是查看click事件的坐标,看看它是否与textNode重叠.

首先,我们需要一个小辅助方法来帮助我们跟踪一组约束中是否存在一组坐标.这将使我们更容易任意确定一组x/y值是否在一组维度内:

function isInside ( x, y, rect ) {
    return x >= rect.left  && y >= rect.top
        && x <= rect.right && y <= rect.bottom;
}
Run Code Online (Sandbox Code Playgroud)

这是相当基本的.的x和y值将是数字,并且rect参考值将是一个对象与至少四个属性保持表示一个矩形的四个角的绝对像素值.

接下来,我们需要一个循环遍历textNodes的所有childNode的函数,并确定是否在其中一个上面发生了click事件:

function textNodeFromPoint( element, x, y ) {
    var node, nodes = element.childNodes, range = document.createRange();
    for ( var i = 0; node = nodes[i], i < nodes.length; i++ ) {
        if ( node.nodeType !== 3 ) continue;
        range.selectNodeContents(node);
        if ( isInside( x, y, range.getBoundingClientRect() ) ) {
            return node;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

完成所有这些后,我们现在可以快速确定textNode是否直接位于所单击的区域下方,并获取该节点的值:

element.addEventListener( "click", function ( event ) {
    if ( event.srcElement === this ) {
        var clickedNode = textNodeFromPoint( this, event.clientX, event.clientY );
        if ( clickedNode ) {
            alert( "You clicked: " + clickedNode.nodeValue );
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

请注意,初始条件if ( event.srcElement ) === this允许我们忽略源自嵌套元素的单击事件,例如图像或span标记.在textNodes上发生的点击将显示父元素srcElement,因此这些是我们唯一关注的元素.

你可以在这里看到结果:http://jsfiddle.net/jonathansampson/ug3w2xLc/