如何在 Amazon.com 的热门广告上放置 div

How to position divs on top ads on Amazon.com

我想在 Amazon.com 上的所有广告之上放置一些 div,如下所示:

这是我的一个项目。上图是通过getBoundingClientRect 获取广告的坐标并创建div,根据这些坐标设置top 和left,并将div 附加到document.body 来实现的。但是,由于它们具有绝对位置并且是 document.body 中的 children,因此它们不会随广告移动。例如,如果我调整 window、this happens

的大小

此外,在产品页面中,this happens without doing anything

我也试过将 div 附加到 iframes/ads 的 parent,但我似乎永远无法让它们出现在 parent 之外.我尝试了各种链接的建议,例如制作 position:absolute、设置底部或顶部、制作 parents position:relative,但没有任何效果。有一个 div 实例出现在 parent 之外,但它位于其上方的某个随机位置 like this.

我真的不知道如何做到这一点。理想情况下,div 将是 iframe 的兄弟或类似的东西,因此我不必处理 div 在 window 调整大小时不移动的问题。不过,我似乎什么也做不了。

    // Here is the code for appending to parent of iframes.
    // The divs just end up overlaying the ad.
    function setStyle(element, styleProperties) {
        for (var property in styleProperties) {
            element.style[property] = styleProperties[property];
        }
    }

    // Regex for getting all the parents of all the iframes
    var placements = document.querySelectorAll('div[id^=\'ape_\'][id$=\'placement\']');

    for (var i = 0; i < placements.length; ++i) {
        var placement = placements[i];

        var iframe = placement.getElementsByTagName('iframe')[0];
        var debugDiv = document.createElement('div');
        debugDiv.id = iframe.id + '_debug_div';
        setStyle(debugDiv, {
            'backgroundColor': '#ff0000',
            'height': '30px',
            'display': 'block',
            'position': 'absolute',
            'top': '-30px',
            'zIndex': '16777270',
        });
        alert(placement.id)
        placement.style.position = 'relative'
        placement.appendChild(debugDiv);
    }

编辑:

这是 getBoundingClientRect 代码:

function setStyle(element, styleProperties) {
    for (var property in styleProperties) {
        element.style[property] = styleProperties[property];
    }
}

function createDiv(iframeId, top, left, width) {
    var div = document.createElement('div');
    div.id = iframeId + '_debug_div';
    setStyle(div, {
        'backgroundColor': '#ccffff',
        'backgroundColor': '#ff0000',
        'height': '30px',
        'width': width.toString() + 'px',
        'display': 'block',
        'position': 'absolute',
        'top': (top - 30).toString() + 'px',
        'left': left.toString() + 'px',
        'zIndex': '16777270'
    });

    return div;
}

var placements = document.querySelectorAll('div[id^=\'ape_\'][id$=\'placement\']');

for (var i = 0; i < placements.length; ++i) {
    var placement = placements[i];

    var iframe = placement.getElementsByTagName('iframe')[0];
    var iframeRect = iframe.getBoundingClientRect();
    iframeWidth = iframeRect.right - iframeRect.left;
    var debugDiv = createDiv(iframe.id, iframeRect.top, iframeRect.left, iframeWidth);
    document.body.appendChild(debugDiv);
};

当 window 调整大小时,这将无法正常工作。它在某些广告的产品页面上也无法正常工作。

我想,您想要 select 广告的图片。

const adImages = document.querySelectorAll('your ad images');
for (var i = 0; i < adImages.length; ++i) {
  adImages[i].parent.insertAdjacentHTML('afterbegin', 'your html');
}

您基本上将该父元素的第一个子元素设置在顶部。

尝试使用 resize 事件侦听器和 DOM MutationObserver:

var observeDOM = (function(){
  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

  return function( obj, callback ){
    if( !obj || !obj.nodeType === 1 ) return; // validation

    if( MutationObserver ){
      // define a new observer
      var obs = new MutationObserver(function(mutations, observer){
          callback(mutations);
      })
      // have the observer observe foo for changes in children
      obs.observe( obj, { childList:true, subtree:true });
    }

    else if( window.addEventListener ){
      obj.addEventListener('DOMNodeInserted', callback, false);
      obj.addEventListener('DOMNodeRemoved', callback, false);
    }
  }
})();

window.onchange = function(){
  observeDOM(document.body, () => {
    window.addEventListener('resize', () => {
      var placements = document.querySelectorAll('div[id^=\'ape_\'] [id$=\'placement\']');

      for (var i = 0; i < placements.length; ++i) {
        var placement = placements[i];

        var iframe = placement.getElementsByTagName('iframe')[0];
        var iframeRect = iframe.getBoundingClientRect();
        iframeWidth = iframeRect.right - iframeRect.left;
        var debugDiv = createDiv(iframe.id, iframeRect.top, iframeRect.left, iframeWidth);
        document.body.appendChild(debugDiv);
      }
    });
  });
}

这是一个开始。我认为产品页面上错误放置的栏的问题也可以通过使用 onload 侦听器来解决,尽管我出于某种原因无法重现这些问题。如果它没有完全匹配某些广告,那可能是由于您的查询选择器造成的,但很遗憾,我无法帮助解决这个问题。

DOM 观察者的代码来自 here - 它应该比 onchange 更准确地检测变化,尤其是对于像 flex 这样的元素可以获取的东西在 DOM 移动视图中重新排序。您可能还想将其包装在 document.addEventListener("DOMContentLoaded", ... 中以等待所有内容加载完毕(牺牲 IE8),或者只使用 jQuery 的 $(document).ready() 与 IE8 兼容) - 但是,如果您还没有使用 jQuery,不要只为这个功能导入它!

此外,您可能想对主体的填充做些处理,这在某些情况下可能是导致未对齐的原因。您可能应该使用 window.getComputedStyles 获取它并对其进行补偿。然而,我再次无法重现这些错误。