DomMarkers 和 DomIcons 无法在 ShadowRoot 内工作

发布于 2025-01-12 23:13:39 字数 936 浏览 5 评论 0原文

我正在尝试在 ShadowRoot 中使用 DomMakers 和 DomIcons。当标记加载时,我收到此错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'getPropertyValue')
at rm.Ga (mapsjs-core.js:350:435)
at kn (mapsjs-core.js:376:338)
at S.Ga (mapsjs-core.js:376:52)
at T.de (mapsjs-core.js:408:437)
at $o (eval at <anonymous> (mapsjs-core.js:73:36), <anonymous>:5:219)
at Zo (eval at <anonymous> (mapsjs-core.js:73:36), <anonymous>:4:425)
at fp.g (eval at <anonymous> (mapsjs-core.js:73:36), <anonymous>:16:301)

发生这种情况是因为mapsjs-core无法找到canvas元素,因为它位于ShadowRoot内部。以下是发生错误的代码片段:

var r = g.style;
f.push({
  Aj: r.getPropertyValue(tm),
  bo: r.getPropertyPriority(tm),
  style: r
});

g 应该是地图画布,但在 ShadowRoot 内部,它是

我正在使用 Here Maps API for Javascript 的 document 元素React 应用程序上的 v3.1.30.7。

如果我更改为标记和图标,问题就消失了,但我失去了所需的交互性。

I'm trying to use DomMakers and DomIcons inside a ShadowRoot. When the markers load, I get this error:

Uncaught TypeError: Cannot read properties of undefined (reading 'getPropertyValue')
at rm.Ga (mapsjs-core.js:350:435)
at kn (mapsjs-core.js:376:338)
at S.Ga (mapsjs-core.js:376:52)
at T.de (mapsjs-core.js:408:437)
at $o (eval at <anonymous> (mapsjs-core.js:73:36), <anonymous>:5:219)
at Zo (eval at <anonymous> (mapsjs-core.js:73:36), <anonymous>:4:425)
at fp.g (eval at <anonymous> (mapsjs-core.js:73:36), <anonymous>:16:301)

This happens because mapsjs-core can't find the canvas element, since it's inside a ShadowRoot. Here is the code snippet where the error occurs:

var r = g.style;
f.push({
  Aj: r.getPropertyValue(tm),
  bo: r.getPropertyPriority(tm),
  style: r
});

g is supposed to be the map canvas, but inside a ShadowRoot it's the document element

I'm using Here Maps API for Javascript v3.1.30.7 on a React app.

If I change to Markers and Icons the problem is gone, but I lose the interactivity I need.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

杯别 2025-01-19 23:13:39

它只能以这种方式工作:

https://jsfiddle.net/ba2oL057/2/

function drawCanvas() {
  var canvas = document.createElement('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.fillRect(25, 25, 100, 100);
    ctx.clearRect(45, 45, 60, 60);
    ctx.strokeRect(50, 50, 50, 50);
  }
  return canvas;
}


/**
 * Create a marker that is capable of receiving DOM events and add it
 * to the map.
 *
 * @param  {H.Map} map      A HERE Map instance within the application
 */
function addDomMarker(map) {
  
  function setToShadow(outerElement){
          var innerElement = document.createElement('div');

      outerElement.attachShadow({mode: 'open'});
      outerElement.shadowRoot.innerHTML = `
        <div></div>
      `;
      let outerShElem = outerElement.shadowRoot.querySelectorAll('div')[0];

      outerShElem.style.userSelect = 'none';
      outerShElem.style.webkitUserSelect = 'none';
      outerShElem.style.msUserSelect = 'none';
      outerShElem.style.mozUserSelect = 'none';
      outerShElem.style.cursor = 'default';

      innerElement.style.color = 'red';
      innerElement.style.backgroundColor = 'blue';
      innerElement.style.border = '2px solid black';
      innerElement.style.font = 'normal 12px arial';
      innerElement.style.lineHeight = '12px'

      innerElement.style.paddingTop = '2px';
      innerElement.style.paddingLeft = '4px';
      innerElement.style.width = '20px';
      innerElement.style.height = '20px';

      // add negative margin to inner element
      // to move the anchor to center of the div
      innerElement.style.marginTop = '-10px';
      innerElement.style.marginLeft = '-10px';

      outerShElem.appendChild(innerElement);
      outerShElem.appendChild(drawCanvas());

      // Add text to the DOM element
      innerElement.innerHTML = 'C';
      
      outerShElem.addEventListener('mouseover', changeOpacity);
      outerShElem.addEventListener('mouseout', changeOpacityToOne);

  }
  
  var outerElement = document.createElement('div');

  //document.body.appendChild(outerElement);

  function changeOpacity(evt) {
    evt.target.style.opacity = 0.6;
  };

  function changeOpacityToOne(evt) {
    evt.target.style.opacity = 1;
  };

  //create dom icon and add/remove opacity listeners
  var domIcon = new H.map.DomIcon(outerElement, {
    // the function is called every time marker enters the viewport
    onAttach: function(clonedElement, domIcon, domMarker) {
      setToShadow(clonedElement);
    },
    // the function is called every time marker leaves the viewport
    onDetach: function(clonedElement, domIcon, domMarker) {
        let outerShElem = clonedElement.shadowRoot.querySelectorAll('div')[0];
      outerShElem.removeEventListener('mouseover', changeOpacity);
      outerShElem.removeEventListener('mouseout', changeOpacityToOne);
    }
  });

  // Marker for Chicago Bears home
  var bearsMarker = new H.map.DomMarker({lat: 41.8625, lng: -87.6166}, {
    icon: domIcon
  });
  map.addObject(bearsMarker);
  //setTimeout(()=>{map.removeObject(bearsMarker);}, 0);
}

/**
 * Boilerplate map initialization code starts below:
 */

//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
  apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();

//Step 2: initialize a map - this map is centered over Chicago.
var map = new H.Map(document.getElementById('map'),
  defaultLayers.vector.normal.map,{
  center: {lat:41.881944, lng:-87.627778},
  zoom: 11,
  pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());

//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));


// Now use the map as required...
addDomMarker(map);

It works only in this way:

https://jsfiddle.net/ba2oL057/2/

function drawCanvas() {
  var canvas = document.createElement('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.fillRect(25, 25, 100, 100);
    ctx.clearRect(45, 45, 60, 60);
    ctx.strokeRect(50, 50, 50, 50);
  }
  return canvas;
}


/**
 * Create a marker that is capable of receiving DOM events and add it
 * to the map.
 *
 * @param  {H.Map} map      A HERE Map instance within the application
 */
function addDomMarker(map) {
  
  function setToShadow(outerElement){
          var innerElement = document.createElement('div');

      outerElement.attachShadow({mode: 'open'});
      outerElement.shadowRoot.innerHTML = `
        <div></div>
      `;
      let outerShElem = outerElement.shadowRoot.querySelectorAll('div')[0];

      outerShElem.style.userSelect = 'none';
      outerShElem.style.webkitUserSelect = 'none';
      outerShElem.style.msUserSelect = 'none';
      outerShElem.style.mozUserSelect = 'none';
      outerShElem.style.cursor = 'default';

      innerElement.style.color = 'red';
      innerElement.style.backgroundColor = 'blue';
      innerElement.style.border = '2px solid black';
      innerElement.style.font = 'normal 12px arial';
      innerElement.style.lineHeight = '12px'

      innerElement.style.paddingTop = '2px';
      innerElement.style.paddingLeft = '4px';
      innerElement.style.width = '20px';
      innerElement.style.height = '20px';

      // add negative margin to inner element
      // to move the anchor to center of the div
      innerElement.style.marginTop = '-10px';
      innerElement.style.marginLeft = '-10px';

      outerShElem.appendChild(innerElement);
      outerShElem.appendChild(drawCanvas());

      // Add text to the DOM element
      innerElement.innerHTML = 'C';
      
      outerShElem.addEventListener('mouseover', changeOpacity);
      outerShElem.addEventListener('mouseout', changeOpacityToOne);

  }
  
  var outerElement = document.createElement('div');

  //document.body.appendChild(outerElement);

  function changeOpacity(evt) {
    evt.target.style.opacity = 0.6;
  };

  function changeOpacityToOne(evt) {
    evt.target.style.opacity = 1;
  };

  //create dom icon and add/remove opacity listeners
  var domIcon = new H.map.DomIcon(outerElement, {
    // the function is called every time marker enters the viewport
    onAttach: function(clonedElement, domIcon, domMarker) {
      setToShadow(clonedElement);
    },
    // the function is called every time marker leaves the viewport
    onDetach: function(clonedElement, domIcon, domMarker) {
        let outerShElem = clonedElement.shadowRoot.querySelectorAll('div')[0];
      outerShElem.removeEventListener('mouseover', changeOpacity);
      outerShElem.removeEventListener('mouseout', changeOpacityToOne);
    }
  });

  // Marker for Chicago Bears home
  var bearsMarker = new H.map.DomMarker({lat: 41.8625, lng: -87.6166}, {
    icon: domIcon
  });
  map.addObject(bearsMarker);
  //setTimeout(()=>{map.removeObject(bearsMarker);}, 0);
}

/**
 * Boilerplate map initialization code starts below:
 */

//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
  apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();

//Step 2: initialize a map - this map is centered over Chicago.
var map = new H.Map(document.getElementById('map'),
  defaultLayers.vector.normal.map,{
  center: {lat:41.881944, lng:-87.627778},
  zoom: 11,
  pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());

//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));


// Now use the map as required...
addDomMarker(map);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文