By jiale ko


2020-02-14 08:27:54 8 Comments

I want to record down the full css path on every element click by user, I follow this answer to create a function that get css path of the clicked element

$('body').on('click',"*",function(){
    var rightArrowParents = [];
    $(this).parents().addBack().not('html').each(function(e) {
        var entry = this.tagName.toLowerCase();

        if($(this).attr('id')){
            entry += "#" + $(this).attr('id');
        }

        if (this.className) {
        entry += "." + this.className.replace(/ /g, '.');
        }

        rightArrowParents.push(entry);
    });
    console.log(rightArrowParents.join(" > "));
})

but I notice that this function is called so many times when I click on an element which is wrap by multiple element,

for example when I click on h1:

body > div.sample1.sample2 > div.sample3.sample4 > h1.test1.test2.test3

body > div.sample1.sample2 > div.sample3.sample4

body > div.sample1.sample2

when I add return false after console.log, it will only output the full css path of h1, which is the expected result, but if I do this, some element will not work properly such as <a> will not redirect to another website

below is what I have tried:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <title>Document</title>
</head>
<body>
    <div class="sample1 sample2">
        <div class="sample3 sample4">
            <h1 class="test1 test2 test3">some example text</h1>
        </div>
    </div>
    <div>
        <h1 class="test1 test2 test3">some sample text</h1>
    </div>
    <div class="sample1 sample2">
        <div class="sample3 sample4">
            <a class="test1 test2 test3" href="https://www.google.com/">henlo</a>
        </div>
    </div>
    <script>
        jQuery(function($){
            $('body').on('click',"*",function(){
                var rightArrowParents = [];
                $(this).parents().addBack().not('html').each(function(e) {
                    var entry = this.tagName.toLowerCase();

                    if($(this).attr('id')){
                        entry += "#" + $(this).attr('id');
                    }

                    if (this.className) {
                    entry += "." + this.className.replace(/ /g, '.');
                    }

                    rightArrowParents.push(entry);
                });
                console.log(rightArrowParents.join(" > "));
                //can't do this, since it will make some element malfunction
                //return false
            })
        })
    </script>
</body>
</html>

what should I do to make the jQuery work properly?

2 comments

@ZPiDER 2020-02-14 08:48:56

This solution may look a bit hacky, but it gets the job done. along these lines there may also be a more elegant solution (like to compare some property of the event for cancellation.

jQuery(function($){
    $('body').on('click',"*",function(e) {
        // mark the event as seen and cancel it it was seen
        if (e.seen) return;
        e.seen = true;
        
        var rightArrowParents = [];
        $(this).parents().addBack().not('html').each(function(i, o) {
            var entry = this.tagName.toLowerCase();

            if($(this).attr('id')){
                entry += "#" + $(this).attr('id');
            }

            if (this.className) {
            entry += "." + this.className.replace(/ /g, '.');
            }

            rightArrowParents.push(entry);
        });
        console.log(rightArrowParents.join(" > "));
    })
})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <title>Document</title>
</head>
<body>
    <div class="sample1 sample2">
        <div class="sample3 sample4">
            <h1 class="test1 test2 test3">some example text</h1>
        </div>
    </div>
    <div>
        <h1 class="test1 test2 test3">some sample text</h1>
    </div>
    <div class="sample1 sample2">
        <div class="sample3 sample4">
            <a class="test1 test2 test3" href="https://www.google.com/">henlo</a>
        </div>
    </div>
</body>
</html>

@Dumisani 2020-02-14 08:43:41

If I understand your question clearly, all you need to do is add an event parameter to your function function(e), then use e.stopPropagation() at the end to prevent it from going through the event handlers of the parent elements.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <title>Document</title>
</head>

<body>
  <div class="sample1 sample2">
    <div class="sample3 sample4">
      <h1 class="test1 test2 test3">some example text</h1>
    </div>
  </div>
  <div>
    <h1 class="test1 test2 test3">some sample text</h1>
  </div>
  <div class="sample1 sample2">
    <div class="sample3 sample4">
      <a class="test1 test2 test3" href="https://www.google.com/">henlo</a>
    </div>
  </div>
  <script>
    jQuery(function($) {
      $('body').on('click', "*", function(e) {
        var rightArrowParents = [];
        $(this).parents().addBack().not('html').each(function() {
          var entry = this.tagName.toLowerCase();

          if ($(this).attr('id')) {
            entry += "#" + $(this).attr('id');
          }

          if (this.className) {
            entry += "." + this.className.replace(/ /g, '.');
          }

          rightArrowParents.push(entry);
        });
        console.log(rightArrowParents.join(" > "));
        
        e.stopPropagation();
      })
    })
  </script>
</body>

</html>

Related Questions

Sponsored Content

10 Answered Questions

[SOLVED] jQuery selector regular expressions

27 Answered Questions

[SOLVED] Trigger a button click with JavaScript on the Enter key in a text box

18 Answered Questions

[SOLVED] jQuery checkbox change and click event

11 Answered Questions

[SOLVED] jQuery multiple events to trigger the same function

36 Answered Questions

[SOLVED] Use jQuery to hide a DIV when the user clicks outside of it

  • 2009-09-10 06:11:27
  • Scott Yu - Front-End UX
  • 708565 View
  • 955 Score
  • 36 Answer
  • Tags:   jquery html hide styling

3 Answered Questions

[SOLVED] Cannot display HTML string

4 Answered Questions

11 Answered Questions

[SOLVED] jQuery's jquery-1.10.2.min.map is triggering a 404 (Not Found)

4 Answered Questions

[SOLVED] content from divs into textarea

6 Answered Questions

[SOLVED] Wildcards in jQuery selectors

Sponsored Content