当前位置: 首页 > 知识库问答 >
问题:

我正在尝试将react bootstrap手风琴绑定到一个传单.js标记上。单击手风琴时,标记将放大

秦胡媚
2023-03-14

我正在尝试将react bootstrap手风琴绑定到一个传单.js标记上。当点击手风琴,标记将被放大。。。问题是我必须“双击”手风琴才能折叠它并放大标记=

**codesandbox演示**

https://codesandbox.io/s/react-leaflet-with-imageoverlay-add-remove-markers-dynamically-2tmex

地图容器

import React, { useEffect, useState } from "react";
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import masterplan from "./img/masterplan.jpg";






let map;
const markerIcon = 'https://www.pinclipart.com/picdir/big/141-1410207_marker-filled-icon-location-logo-png-file-clipart.png'
const editMarkerIcon = 'https://cdn.iconscout.com/icon/premium/png-256-thumb/marker-1829264-1551716.png'
var myIcon = L.icon( {
  iconUrl: markerIcon,
  iconSize: [ 30, 35 ],
  iconAnchor: [ 15, 35 ],
  popupAnchor: [ 0, -40 ],
} );

var editMyIcon = L.icon( {
  iconUrl: editMarkerIcon,
  iconSize: [ 50, 40 ],
  iconAnchor: [ 25, 35 ],
  popupAnchor: [ 0, -40 ],


} );




const MapContainer = ( { data, linkName, formCss, addMarker, isMarkerAdded, setIsMarkerAdded, formData, setFormData, setGetMarkerObject, setMarkersList, setEdit, clicked, setClicked } ) => {



  const [ coordinates, setCoordinates ] = useState( { lats: 0, lngs: 0 } )

  // setting up the map with the image inside
  const MaxMapMBounds = [ [ 0.047356142676201576,
    -0.05648240856298255 ], [ -0.09911669921875, 0.05903846615873286 ] ]


  // building the map container
  const buildMap = () => {


    map = L.map( 'map', {
      crs: L.CRS.Simple,
      maxBounds: MaxMapMBounds,
      minZoom: 13,
      maxZoom: 15,
      maxBoundsViscosity: 0.0,

    } ).setView( [ 0, 0 ], 13 );



    // rendering the image inside the map 

    var imageBounds = [ [ 0.0484693481114499, -0.0652342559975141 ], [ -0.03143095517869242, 0.06518541415112039 ] ];

    const image = L.imageOverlay(
      masterplan,
      imageBounds,
      { className: 'image-map' },
    ).addTo( map );


    // Logging coordinates when clicking on the map
    map.on( 'click', function ( e ) {
      var coord = e.latlng;
      var lat = coord.lat;
      var lng = coord.lng;

      console.log( `latitude: ${ lat } and longitude: ${ lng } === [${ lat } ,
 ${ lng } ]` );
    } );


    return map
  }


  useEffect( () => {

    buildMap()
    addMarkers()
    renderMarkers()


    return () => {
      map.off();
      map.remove();

    }

  }, [ data, ] );



  // // adding markers from  FormMarker with draggable markers available

  const addMarkers = ( editedMarkerLatLng ) => {
    if ( addMarker )
    {

      let marker;


      // adding markers
      if ( isMarkerAdded === false )
      {
        let onDrag = function ( e ) {
          let latlng = marker.getLatLng();
          setCoordinates( { lats: latlng.lat, lngs: latlng.lng } )
          setFormData( { ...formData, coordinates: [ latlng.lat, latlng.lng ] } )

          // showing popup when dragging
          marker.bindPopup().openPopup()
        };



        let onClick = function ( e ) {

          setIsMarkerAdded( true )
          map.off( 'click', onClick ); //turn off listener for map click



          marker = L.marker( e.latlng, { icon: editMyIcon, draggable: true } ).addTo( map ).bindPopup( '<p>انا هنا يا جون</p>', { closePopupOnClick: false, autoClose: false, closeOnClick: false, } ).openPopup();


          // updating coordinates <p> on the ui
          setCoordinates( { lats: e.latlng.lat, lngs: e.latlng.lng } )

          // updating coordinates on the form
          setFormData( { ...setFormData, coordinates: [ e.latlng.lat, e.latlng.lng ] } )

          marker.on( 'drag', onDrag );

          // removing popup after adding the marker to markersList
          setGetMarkerObject( marker )
        };
        map.on( 'click', onClick );
      }





    }
  }





  //    rendering Markers of the Units inside the map &&& Focusing on selected unit by touching on its button link

  const renderMarkers = () => {


    data && data.map( ( link ) => {

      let marker



      if ( addMarker )
      {
        // rendering markers at add-marker page
        var container = L.DomUtil.create( 'div' );
        const createButton = ( label, container, className ) => {
          var btn = L.DomUtil.create( 'button', '', container );
          btn.setAttribute( 'type', 'button' );
          btn.setAttribute( 'class', className );
          btn.innerHTML = label;
          return btn;
        }

        const createParagraph = ( label, container, className ) => {
          var para = L.DomUtil.create( 'p', '', container );

          para.setAttribute( 'class', className );
          para.innerHTML = label;
          return para;
        }
        const editButton = createButton( 'Edit marker', container, 'edit-button' );
        const removeButton = createButton( 'Remove marker', container, 'remove-button' );
        const popupText = createParagraph( `Name: ${ link.name }`, container, 'popup-text' )

        L.DomEvent.on( editButton, 'click', () => handleEditMarker( marker ) );
        L.DomEvent.on( removeButton, 'click', () => handleRemoveMarker( marker ) );
        return marker = L.marker( L.latLng( link.markerPosition ), { icon: myIcon } ).addTo( map ).bindPopup( container )
      }



      // rendering markers at home page 

      marker = L.marker( L.latLng( link.markerPosition ), { icon: myIcon } ).addTo( map ).bindPopup( link.markerText )
      if ( link.name === linkName )
      {
        // Focusing on selected unit by touching on its button link


        let unitMarker = L.polygon( link.latlng, { fill: false, opacity: 0 } ).addTo( map )
        marker.openPopup()
        map.fitBounds( unitMarker.getBounds() )
        // setClicked( true )
      }
    } )

  }
  const handleEditMarker = ( marker ) => {
    setIsMarkerAdded( true )
    setEdit( true )
    const lat = marker._latlng.lat
    const lng = marker._latlng.lng
    let editedMarker = data.find( item => item.markerPosition[ 0 ] === lat && item.markerPosition[ 1 ] === lng )
    handleRemoveMarker( marker )


    setFormData( { ...editedMarker, coordinates: [ lat, lng ] } )

    marker = L.marker( [ lat, lng ], { icon: editMyIcon, draggable: true } ).addTo( map ).bindPopup( '<p>انا هنا يا جون</p>', { closePopupOnClick: false, autoClose: false, closeOnClick: false, } ).openPopup();


    let onDrag = function ( e ) {
      let latlng = marker.getLatLng();
      // setCoordinates( { lats: latlng.lat, lngs: latlng.lng } )
      setFormData( { ...editedMarker, coordinates: [ latlng.lat, latlng.lng ] } )

      // showing popup when dragging
      marker.bindPopup().openPopup()

    };
    marker.on( 'drag', onDrag );
    setGetMarkerObject( marker )




  }

  const handleRemoveMarker = ( marker ) => {

    const lat = marker._latlng.lat
    const lng = marker._latlng.lng

    let tempMarkers = data.filter( item => item.markerPosition[ 0 ] !== lat && item.markerPosition[ 1 ] !== lng )
    setMarkersList( tempMarkers )


  }


  return (
    <div className={ formCss ? 'map-container-form' : 'map-container' }>

      <div id="map"

      ></div>
      { formCss &&

        <p>coordinates: { `[ ${ coordinates.lats }, ${ coordinates.lngs } ]` }</p>
      }

    </div>
  );
};

export default MapContainer
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

手风琴部件

import React, { useEffect } from 'react'
import { Accordion, useAccordionButton } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';



const AccordionComp = ( { link, handleLink } ) => {



 return (

  <Accordion.Item eventKey={ link.id } onClick={ ( e ) => {
   handleLink( e, link.name )
  } } >
   <Accordion.Header >
    { link.name }
   </Accordion.Header>

   <Accordion.Body>

    <p><b> Type: </b>{ link.type }</p>
    <p><b> Area: </b>{ link.area } ( ㎡ )</p>
    <p><b> Price: </b> { link.price } (LE)</p>
    <p><b> Description: </b> { link.description }</p>
   </Accordion.Body>
  </Accordion.Item>


 )
}

export default AccordionComp
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

应用程序组件

**问题是当我点击手风琴时,调用“handleLink”fn来使用setLinkName更新linkName状态。。。。当我注释掉setLinkName fn时=

import './App.css';
import React, { useState, useEffect } from 'react'
import { data } from './data'
import MapContainer from './MapContainer'
import { Route, Switch } from "react-router-dom";
import FormMarker from './FormMarker';
import AccordionComp from './components/AccordionComp';
import { Accordion } from 'react-bootstrap';



const App = () => {

 const [ clicked, setClicked ] = useState( false )
 const [ linkName, setLinkName ] = useState( null )
 const initialMarkersList = localStorage.getItem( "markersList" )
  ? JSON.parse( localStorage.getItem( "markersList" ) )
  : [];


 const handleLink = ( e, linkName ) => {

  setLinkName( linkName )
 }


 const Home = () => {
  return (
   <div className="App">

    <div className="links">
     <Accordion   >
      { initialMarkersList && initialMarkersList.map( ( link ) => {

       return <AccordionComp key={ link.id } link={ link } setLinkName={ setLinkName } handleLink={ handleLink } setClicked={ setClicked } />
      } ) }
     </Accordion>
    </div>

    <MapContainer data={ initialMarkersList } linkName={ linkName } clicked={ clicked } setClicked={ setClicked } />
   </div>
  )
 }

 useEffect( () => {
  console.log( document.getElementsByClassName( 'accordion-collapse' )[ 0 ].classList );

 }, [] )


 console.log( linkName, 'linkname' );
 console.log( clicked, 'clickde' );

 return (
  <>
   <Switch>
    <Route path="/" exact component={ Home } />
    <Route path="/add-marker" exact component={ FormMarker } />

   </Switch >
  </>
 )
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

共有1个答案

劳法
2023-03-14

答案是将App comp中的状态和方法移动到已经在App comp中的Home comp中

 

import './App.css';
import React, { useState, useEffect } from 'react'
import { data } from './data'
import MapContainer from './MapContainer'
import { Route, Switch } from "react-router-dom";
import FormMarker from './FormMarker';
import AccordionComp from './components/AccordionComp';
import { Accordion } from 'react-bootstrap';



const App = () => {

 


 const Home = () => {
 
 
 const [ clicked, setClicked ] = useState( false )
 const [ linkName, setLinkName ] = useState( null )
 const initialMarkersList = localStorage.getItem( "markersList" )
  ? JSON.parse( localStorage.getItem( "markersList" ) )
  : [];


 const handleLink = ( e, linkName ) => {

  setLinkName( linkName )
 }
 
  return (
   <div className="App">

    <div className="links">
     <Accordion   >
      { initialMarkersList && initialMarkersList.map( ( link ) => {

       return <AccordionComp key={ link.id } link={ link } setLinkName={ setLinkName } handleLink={ handleLink } setClicked={ setClicked } />
      } ) }
     </Accordion>
    </div>

    <MapContainer data={ initialMarkersList } linkName={ linkName } clicked={ clicked } setClicked={ setClicked } />
   </div>
  )
 }

 useEffect( () => {
  console.log( document.getElementsByClassName( 'accordion-collapse' )[ 0 ].classList );

 }, [] )


 console.log( linkName, 'linkname' );
 console.log( clicked, 'clickde' );

 return (
  <>
   <Switch>
    <Route path="/" exact component={ Home } />
    <Route path="/add-marker" exact component={ FormMarker } />

   </Switch >
  </>
 )
}

export default App;

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
 类似资料:
  • 手风琴效果其实就是通过JS改变元素的height,然后加上transition来让css动起来。 准备HTML结构 这里我们使用 dl , 因为 dt 刚好可以模拟标题, dd 模拟内容。 <div class="panel"> <dl> <dt>One Item</dt> <dd>One Item Content .</dd>

  • 我正在使用jQuery手风琴来隐藏一些数据。 accordion标题是一个带有一些标题的表格。有一个标题,我不希望你点击它,因为手风琴事件会触发。 所以 手风琴是可折叠的,如果您单击Test2(类nofunction),手风琴事件不应触发。但是如果您单击Test或其他表头,手风琴应该会触发事件。 我可以添加这个功能吗? 更新测试http://jsfiddle.net/e3Q8d/,包括jQuery

  • jQueryUI中的Accordion Widget是一个基于jQuery的可扩展和可折叠内容持有者,它被分成几个部分,可能看起来像标签。 jQueryUI提供了accordion()方法来实现这一点。 语法 (Syntax) accordion()方法可以使用两种形式 - $(selector,context).accordion(options)方法 $(selector, context).

  • 描述 (Description) 手风琴是一个图形控制元素,显示为堆叠的项目列表。 每个手风琴都可以expanded或stretched以显示与手风琴相关的内容。 可折叠布局 当您使用单个单独的可折叠元素时,您需要省略accordion-list包装元素。 以下是可折叠布局的结构 - <!-- Single collapsible element ------> <div class = "acc

  • 我尝试了以下代码,除了图标外,一切都很好。我试图在Google上找到一些解决方案,但我找不到我正在寻找的解决方案。 当我点击其中一个手风琴时,另一个手风琴应该折叠,当前点击的手风琴应该打开,同时fa图标应该根据手风琴的位置而改变。 这是我到目前为止已经尝试过的

  • 本文向大家介绍js实现简单的手风琴效果,包括了js实现简单的手风琴效果的使用技巧和注意事项,需要的朋友参考一下 效果图: 图(1)初始图 图(2)点击展开效果 代码如下: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!