我正在尝试将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>
答案是将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)点击展开效果 代码如下: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!