代码之家  ›  专栏  ›  技术社区  ›  machineghost

如何使单击事件仅触发文本(而不是同一元素中的其他空白)[重复]

  •  1
  • machineghost  · 技术社区  · 7 年前

    我有一个Div,使用CSS时,它的大小相当于我页面的一半:

    <div id="bigdiv">
         CLICK ON THIS TEXT
    </div>
    

    0 回复  |  直到 11 年前
        1
  •  9
  •   Sampson    11 年前

    因为我们不能直接在textNodes上监听事件,所以我们必须采取更具创造性的方法来解决这个问题。我们可以做的一件事是查看click事件的坐标,看看它是否与textNode重叠。

    在内部 该模型包含一组尺寸:

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

    这是相当基本的。这个 x y rect 引用将是至少具有四个属性的对象,其中包含表示矩形四个角的绝对像素值。

    接下来,我们需要一个函数来循环遍历所有作为TextNode的ChildNode,并确定单击事件是否发生在其中一个上面:

    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;
    }
    

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

    注意,初始条件 if ( event.srcElement ) === this srcElement 因此,这些是我们唯一关心的问题。

    您可以在此处看到结果: http://jsfiddle.net/jonathansampson/ug3w2xLc/

        2
  •  1
  •   atrifan    11 年前

    <div id="bigdiv">
        <span id="text">TEXT HERE</span>
    </div>
    
    Script:
    $('#text').on('click', function() {
       .....
    });
    
        3
  •  1
  •   atrifan    11 年前

    <div id="gig">
    <div id="smthing">one</div>lala
    <div id="else"></div>
    </div>
    
    Script:
    
    var htmlText = $('#gig').text(); //the big divs text
    
    
        var children = $('#gig').children(); //get dom elements so they can be ignored later
    
        $.each(children, function (index, child) {
            var txt = $(child).text().trim(); 
            if (txt != '') { //if a child has text in him
                htmlText = htmlText.replace(txt, 'xxx'); //replace it in the big text with xxx
            }
        });
    
        htmlText = htmlText.split("xxx"); //split for xxx make it arrat
        var counter = 0; //the part when the text is added
        $.each(htmlText, function (i, el) {
            htmlText[i] = el.trim();
    
            if (htmlText[i] != "") { //if there is something here than it's my text
                htmlText[i] = '<span id="text">' + htmlText[i] + '</span>'; //replace it with a HTML element personalized
                counter++; //mark that you have replaced the text
            } else { // if there is nothing at this point it means that I have a DOM element here
                htmlText[i] = $(children[i - counter])[0].outerHTML; //add the DOM element
            }
        });
    
        if (children.length >= htmlText.length) { //you might have the case when not all the HTML children were added back 
            for (var i = htmlText.length - 1; i < children.length; i++) {
                htmlText[i + 1] = $(children[i])[0].outerHTML; //add them
            }
        }
    
        htmlText = htmlText.join(""); //form a HTML markup from the altered stuff
    
        $('#gig').html(htmlText); // replace the content of the big div
    
        $('#text').on('click', function (data) { //add click support
            alert('ok');
        });
    

    http://jsfiddle.net/atrifan/5qc27f9c/

    对不起,我有点累了。

    你能做到这一点吗?这就是你想要的吗?

    它只生成div中的文本,尽管div也可以有其他div,只生成没有HTML容器的文本,比如div a span a p an a或类似的内容,并对其进行修改,将其添加到一个span中,使其可供单击。

        4
  •  1
  •   Thijs Riezebeek    11 年前


    在没有包装元素的情况下执行此操作相当麻烦。我设法让它工作,但这将 仅适用于垂直和水平居中的一个衬里

    要查看与此相关的HTML和CSS,请参阅 http://jsfiddle.net/v8jbsu3m/3/

    jQuery('#bigDiv').click(function(e) {
        // Get the x and y offest from the window
        margin_top = jQuery(this).offset().top;
        margin_left = jQuery(this).offset().left;
    
        // Get the dimensions of the element.
        height = jQuery(this).height();
        width = jQuery(this).width();
    
        // Retrieve the font_size and remove the px addition
        font_size = parseInt(jQuery(this).css('font-size').replace('px', ''));
    
        // Retrieve the position of the click
        click_x = e.pageX;
        click_y = e.pageY;
    
        // These variables will be used to validate the end result
        var in_text_y = false;
        var in_text_x = false;
    
        // Determine the click relative to the clicked element
        relative_x = click_x - margin_left;
        relative_y = click_y - margin_top;
    
        // Determine whether the y-coordinate of the click was in the text
        if (relative_y >= (parseFloat(height) / 2) - (parseFloat(font_size) / 2) &&
            relative_y <= (parseFloat(height) / 2) + (parseFloat(font_size) / 2))
            in_text_y = true;
    
        // This piece of code copies the string and places it in a invisible div
        // If this div has the same font styling and no paddings etc... it can
        // be used to get the width of the text
        text = jQuery(this).text();
        text_width = jQuery('#widthTester').html(text).width();
    
         // Determine whether the x-coordinate of the click was in the text
        if (relative_x >= (parseFloat(width) / 2) - (parseFloat(text_width) / 2) &&
            relative_x < (parseFloat(width) / 2) + (parseFloat(text_width) / 2))
            in_text_x = true;
    
        // If the x and y coordinates were both in the text then take action
        if (in_text_x && in_text_y)
            alert('You clicked the text!');
    });
    

    通过添加包装元素来解决此问题

    如果在文本周围放置一个span,则可以向span中添加onClick事件处理程序。

    <div id="bigdiv">
         <span>CLICK ON THIS TEXT</span>
    </div>
    

    jQuery代码

    jQuery('#bigdiv span').click(function() {
        jquery(this).remove();
    });
    
        5
  •  -5
  •   Toza    11 年前

    如果您想直接浏览HTML,可以使用

    <div id="bigdiv" onclick="myFunction();">
    

    然后在JS中简单地应用函数:

    function myFunction(){
        //...
    }
    

    <p> 围绕文本或 <span>

    <div id="bigdiv">
        <p onclick="myFuncion();"> TEXT </p>
    </div>