【问题标题】:How can I execute a function when a div with a particular css is created?创建具有特定 css 的 div 时如何执行函数?
【发布时间】:2021-12-03 11:29:51
【问题描述】:

我正在开发一个 tampermonkey 脚本,以便在它出现时填充一个弹出窗口,特别是这个。

所以当页面启动并且我点击一个按钮时,这会创建一个新的弹出窗口,它是一个具有特定类的 div。

这个想法是,当这个弹出窗口启动时,执行一段代码来填充那个弹出窗口。

我正在尝试使用以下代码:

/ ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        
// @icon         https://www.google.com/s2/favicons?domain=atlassian.net
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    document.getElementById('jira-dialog-heading').addEventListener('click', function() {
        alert('do something');
    });

})();

但不起作用。

我该怎么做?

编辑 1

所有代码更新

控制台中没有错误

谢谢

【问题讨论】:

  • 请提供可以重现您的问题的完整代码示例
  • 控制台有错误吗?
  • 刚刚更新了所有代码,控制台中没有错误
  • 弹出窗口是否超出您的控制范围?您是否有可能例如向负责其打开的方法添加回调?
  • 有两种选择。 1st) OP 拥有脚本和/或可以订阅弹出启动过程/事件。在这种情况下,OP 可以编写和/或挂钩自定义事件处理代码。 2nd)OP 不拥有脚本和/或无法订阅弹出启动过程/事件。在这种情况下,OP 需要使用MutationObserver

标签: javascript dom event-handling tampermonkey mutation-observers


【解决方案1】:

从上面的评论...

“有两个选项。1)OP 拥有脚本和/或可以订阅弹出启动过程/事件。在这种情况下,OP 可以编写和/或挂钩自定义事件处理代码。2) OP 不拥有脚本和/或无法订阅弹出启动过程/事件。在这种情况下,OP 需要使用MutationObserver。"

下一个提供的代码针对第二种情况,并尝试涵盖许多可能但合理的弹出窗口如何改变 DOM 的方式...

// custom specific popup handling

function handlePopupShow(popupNode) {
  console.log('handle popup show :: node ...', popupNode);
}
function handlePopupHide(popupNode) {
  console.log('handle popup hide :: node ...', popupNode);
}


// The popup specific mutation handler, the observers callback function.

function handleChildNodeAndClassNameMutation(mutationList/*, observer*/) {
  mutationList.forEach(mutation => {

    const { type, attributeName } = mutation;
    if (type === 'attributes' && attributeName === 'class') {

      const { target } = mutation;
      if (target.matches('.popup-specific-name.show')) {

        handlePopupShow(target);
      } else if (
        target.matches('.popup-specific-name.hide') ||
        target.matches('.popup-specific-name:not(.show)')
      ) {
        handlePopupHide(target);
      }
    } else if (type === 'childList') {
      const {
        addedNodes: [ addedTargetNode ],
        removedNodes: [ removedTargetNode ],
      } = mutation;
      if (
        addedTargetNode?.matches?.('.popup-specific-name')
        // addedTargetNode?.matches?.('.popup-specific-name.show')
      ) {
        handlePopupShow(addedTargetNode);
      } else if (
        removedTargetNode?.matches?.('.popup-specific-name')
      ) {
        handlePopupHide(removedTargetNode);
      }
    }
  });
}
// - The to be observed target node.
// - Due to detecting a popup specifc element
//   it has to be the `document.body`.
const popupMutationTarget = document.body;

// Defines the to be observed popup specific mutations.
const popupMutationConfig = {
  attributeFilter: ['class'],
  childList: true,
  subtree: true,
};

// Create mutation observer.
const popupObserver =
  new MutationObserver(handleChildNodeAndClassNameMutation);

// // Start target node observation for popup specific mutations.
// popupObserver.observe(popupMutationTarget, popupMutationConfig);

// // Does stop the observation.
// popupObserver.disconnect();


// bring test case to life.

function togglePermanentPopup(/* evt */) {
  document
    .querySelector('.popup-specific-name.permanent')
    .classList.toggle('show');
}
function toggleNonPermanentPopup(/* evt */) {
  let popupNode =
    document.querySelector('.popup-specific-name.non-permanent');
  if (popupNode) {
    popupNode.remove();
  } else {
    popupNode = document.createElement('div');
    popupNode.classList.add('popup-specific-name', 'non-permanent');
    popupNode.textContent =
      'non permanent dom element, show and hide by insert and remove';
    document.body.prepend(popupNode);
  }
}
document
  .querySelector('#toggle_permanent_popup')
  .addEventListener('click', togglePermanentPopup);
document
  .querySelector('#toggle_non_permanent_popup')
  .addEventListener('click', toggleNonPermanentPopup);

let inObservation = false;
function toggleObservation({ target }) {
  if (inObservation) {
    // Does stop the observation.
    popupObserver.disconnect();

    target.textContent = 'Start observation';

    console.log('+++ Observer disconnected +++');
  } else {
    // Start target node observation for popup specific mutations.
    popupObserver.observe(popupMutationTarget, popupMutationConfig);

    target.textContent = 'Stop observation';

    console.log('+++ Observer is running +++');
  }
  inObservation = !inObservation;
}
document
  .querySelector('#toggle_observation')
  .addEventListener('click', toggleObservation);
.popup-specific-name {
  display: block;
  position: absolute;
  top: 0;
  width: 100%;
  text-align: center;
  background-color: #cf0;
}
.popup-specific-name.permanent {
  display: none;
  background-color: #fc0;
}
.popup-specific-name.show {
  display: unset;
}
.popup-specific-name + .popup-specific-name {
  top: 20px;
}
button { display: block; position: relative; top: 35px; }
button#toggle_observation { float: right; top: 14px; }

.as-console-wrapper { max-height: 111px!important; }
<div class="popup-specific-name permanent">
  permanent dom element, class name controlled show and hide
</div>

<button id="toggle_permanent_popup">toggle permanant popup</button>
<button id="toggle_non_permanent_popup">toggle non permanant popup</button>
<button id="toggle_observation">Start observation</button>

【讨论】:

    【解决方案2】:

    我会使用 mutationObserver 来完成它:https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe

    来自 MDN:

    MutationObserver 方法 observe() 将 MutationObserver 回调配置为开始接收与给定选项匹配的 DOM 更改通知。

    【讨论】:

    • 这不起作用,返回null,想法是页面加载,为一个id添加一个事件,用和id创建那个div,然后启动那个事件。
    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 2021-11-14
    • 2021-06-16
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2017-09-18
    相关资源
    最近更新 更多