Как отслеживать клики всех пользователей по кнопкам на сайте Jira - PullRequest
1 голос
/ 04 марта 2020

Я пытаюсь всплыть предупреждение, содержащее имя кнопки всякий раз, когда пользователь нажимает ее, не только кнопки, но и теги, теперь проблема в том, что есть разные типы вложения содержимого кнопки, например, это может быть так :

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

или у тега кнопки может быть только один дочерний элемент ..et c. Вот код трех интерактивных элементов:

  • , в первом элементе которого я хочу отобразить «Создать проекты» в окне предупреждения:

  • и некоторые кнопки имеют свои имена в качестве значения атрибута, называемого aria-label, например:

  • в первом элементе, который я хочу отобразить «Проекты» в окно оповещения

Я написал следующий код, и проблема иногда в том, что когда я нажимаю кнопку, предупреждение показывает имя кнопки, а иногда нет, вот мой код:

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

}

и файл манифеста 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
}

Что не так с этим кодом?

1 Ответ

0 голосов
/ 04 марта 2020

Решение не кажется мне простым, поскольку вы не знаете ни класса, ни уникального идентификатора для всех визуальных кнопок ...

Поэтому я предложу один из способов сделать это.

Сначала добавьте глобальный список событий щелчка на document, чтобы вы могли отслеживать все щелчки и просто выбирать то, что вы хотите.

Что-то вроде этого, простой способ увидеть, что вы нажимаете. (может быть, вы можете найти решение именно по этому поводу)

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>

Тогда вам придется каким-то образом внести в белый список, что такое кнопка (поскольку вы не можете взять только теги)

Так что для этого я подумал о создании массива или карты (если возможно) из XPaths и проверки соответствия совпадающего элемента с вашим белым списком. Только тогда вы получите текст.

Примечание: XPath - это уникальный путь узла в DOM. Это также означает, что вам нужно знать все XPath-ы ваших кнопок.
Обычно XPath не являются легкими с точки зрения производительности, но если вы запускаете только по щелчку и находите оптимизированное решение, все должно быть в порядке ...

Вот пример того, о чем я говорю:

// 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>

У меня сейчас нет лучшей идеи, надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...