简体   繁体   English

如何跟踪所有用户对 Jira 网站上按钮的点击

[英]How to track clicks of all the users on buttons on Jira website

I'm trying to pop-up an alert containing the button name whenever the user presses it, not only buttons but also Tags, now the problem is that there's different types of nesting the button content for example it could be like this:我试图在用户按下按钮时弹出一个包含按钮名称的警报,不仅是按钮,还有标签,现在的问题是按钮内容有不同类型的嵌套,例如它可能是这样的:

<button>
  <div>
   //content doesn't matter here
  </div>
  <div>
    <span>Button Name </span> I want to display this span inner text
   </div>
</button>

or the button tag could have only one child..etc.或者按钮标签只能有一个孩子......等等。 Here are the code of three clickable elements:以下是三个可点击元素的代码:

  • in the first element I want to display "Create Projects" in an alert window:在我想在警报窗口中显示“创建项目”的第一个元素中:

  • and some buttons have their names as a value of an attribute called aria-label like this:并且一些按钮的名称是一个名为 aria-label 的属性的值,如下所示:

  • in the first element I want to display "Projects" in an alert window在我想在警报窗口中显示“项目”的第一个元素中

I wrote the following code, and the problem is sometimes when I press the button the alert shows with the button name, and sometimes it doesn't, here's my code:我编写了以下代码,问题是有时当我按下按钮时,警报会显示按钮名称,有时则不会,这是我的代码:

// Queue implementation

class Queue
{
    constructor()
    {
        this.items=[];
    }

    // front function 
    front() 
    { 
        // returns the Front element of  
        // the queue without removing it. 
        if(this.isEmpty()) 
            return "No elements in Queue"; 
        return this.items[0]; 
    } 


    enqueue(element)
    {
        this.items.push(element);
    }

    dequeue()
    {
        if (this.isEmpty()) 
            return " Underflow";
        return this.items.shift();
    }

    isEmpty()
    {
        return this.items.length == 0;
    }
}


function BFS(node) {
    let q = new Queue();
    //let explored = new Set();
    q.enqueue(node);
    while (!q.isEmpty()) {
        let currentChild = q.front();   
        q.dequeue()
        let ChildBoy = currentChild.children;
        for (let i = 0 ; i <ChildBoy.length ; i++) {
            q.enqueue(ChildBoy[i]);
            console.log(ChildBoy[i]);
            //explored.add(ChildBoy[i]);
        }


        if (currentChild.textContent != null && currentChild.textContent != undefined && currentChild.textContent != "") 
        {
            alert("textContent"+ "  "+currentChild.textContent);
            break;
        }
        if (currentChild.getAttribute("aria-label") != "" && currentChild.getAttribute("aria-label") != null && currentChild.getAttribute("aria-label") != undefined) 
        {
            alert("aria-label-Content"+"   "+currentChild.getAttribute("aria-label")); 
        }
    }
}

let buttons = document.getElementsByTagName("button");
for (let index = 0; index < buttons.length; index++) {
    let button_i = buttons[index];
    button_i.addEventListener('click', function () {
       BFS(button_i) ;
    });

}



let hrefs = document.getElementsByTagName("a");
for (let index_1 = 0; index_1 < hrefs.length; index_1++) {
    let hrefs_j = hrefs[index_1];
    hrefs_j.addEventListener('click' , function()
    {
        BFS(hrefs_j);
    });

}

and the manifest json file is:清单 json 文件是:

{
    "name" : "first extension",
    "version" : "1.0",
    "description" : "extension for track user",
    "permissions" : [
        "storage",
        "declarativeContent",
        "activeTab"
    ],
    "page_action" : {
        "default_popup" : "popup.html",
        "default_icon": {
            "16": "images/get_started16.png",
            "32": "images/get_started32.png",
            "48": "images/get_started48.png",
            "128": "images/get_started128.png"
          }

    },
    "background" : {
        "scripts" : 
        ["background.js"],
        "persistent" : true
    },
    "icons": {
        "16": "images/get_started16.png",
        "32": "images/get_started32.png",
        "48": "images/get_started48.png",
        "128": "images/get_started128.png"
      },

      "content_scripts" :
      [
          {
            "matches" :["https://*.atlassian.net/*/*" , "https://*.atlassian.com/*" , "https://*.atlassian.net/*"],
            "js" : ["track.js"]
          }
      ],

    "manifest_version" : 2
}

What's the wrong with this code?这段代码有什么问题?

The solution does not seem straight forward to me, since you do not know a class or a unique identifier for all visual buttons...解决方案对我来说似乎并不直接,因为您不知道所有可视按钮的类或唯一标识符......

Therefore I will propose one way of doing it.因此,我将提出一种方法。

First add a global click event lister on the document this way you can track all the click and just select what you want.首先在document上添加一个全局点击事件列表,这样您就可以跟踪所有点击并选择您想要的。

Something like this, a simple way to see what are you clicking.像这样的东西,一种查看您点击的内容的简单方法。 (maybe you can find a solution just around this) (也许你可以找到一个解决方案)

 document.addEventListener("click", function(event) { const elementType = event.target.tagName; console.log(elementType + ' clicked!'); });
 <div>Test1</div> <span>Test2</span><br> <button>Test3</button><br> <a>Test4</a><br> <button>Test5</button><br> <div> <button>Test6</button> </div> <p>Test7</p>

Then you will have somehow to whitelist what is a button (as you cannot take only the tags)然后您将不得不以某种方式将按钮列入白名单(因为您不能只使用标签)

So for this I was thinking about creating an array or a map (if possible) of XPaths and verify if the clicked element matches with your whitelist.因此,为此我正在考虑创建XPath的数组或映射(如果可能)并验证单击的元素是否与您的白名单匹配。 Only then you will get the text.只有这样你才能得到文本。

Note: XPath is a unique path of a node in DOM.注意:XPath 是 DOM 中节点的唯一路径。 That also means you will have to know all XPaths of your buttons.这也意味着您必须知道按钮的所有 XPath。
Usually XPath are not lightweight on terms of performance, but if you run only on click and you find an optimized solution, it should be ok...通常 XPath 在性能方面不是轻量级的,但是如果您只在单击时运行并找到优化的解决方案,那应该没问题...

Here is an example of what I'm talking about:这是我正在谈论的一个例子:

 // Using object for performance reasons. const ACCEPTED_XPATHS = { '/html/body/button[1]': 1, '/html/body/button[2]': 1, '/html/body/div[2]/button': 1, '/html/body/div[3]/div/span': 1 } document.addEventListener("click", function(event) { const element = event.target; const elementXPath = xpath(element); // You can use this to collect your accepted list: console.log('CLICKED PATH = ' + elementXPath); if (ACCEPTED_XPATHS[elementXPath]) { console.log('BUTTON CLICKED --- Button Text: ' + element.innerHTML); } }); // https://gist.github.com/iimos/e9e96f036a3c174d0bf4 function xpath(el) { if (typeof el == "string") return document.evaluate(el, document, null, 0, null) if (!el || el.nodeType != 1) return '' if (el.id) return "//*[@id='" + el.id + "']" var sames = [].filter.call(el.parentNode.children, function (x) { return x.tagName == el.tagName }) return xpath(el.parentNode) + '/' + el.tagName.toLowerCase() + (sames.length > 1 ? '['+([].indexOf.call(sames, el)+1)+']' : '') }
 <div>Test1</div> <span>Test2</span><br> <button>Test3</button><br> <a>Test4</a><br> <button>Test5</button><br> <div> <button>Test6</button> </div> <p>Test7</p> <div> <div> <span>THIS IS ALSO A BUTTON</span> </div> </div>

I don't have a better idea right now, Hope it helps :)我现在没有更好的主意,希望它有帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM