<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          首頁

          好看的圣誕樹(動態效果) 轉自 csdn

          前端達人

          、制作方法 

          1.復制代碼到Dreamweaver或HBuilder或vscode中

          2.點擊運行---運行到瀏覽器---選擇你要打開的瀏覽器

          3.打開后會出現這個界面,前四個是固定音樂,最后一個是自主選擇的音樂,你可以選擇你電腦上的歌曲,什么歌曲都行(第一次打開可能會有點慢,稍等片刻即可,選擇音樂的時候點一下沒反應的話多點幾下即可,第一次打開這屬于正?,F象)

           

          4.特別提醒:打開的時候電腦一定要處于聯網狀態
           

          三、源代碼

           
          1.  
            <!DOCTYPE html>
          2.  
            <html lang="en">
          3.  
             
          4.  
            <head>
          5.  
            <meta charset="UTF-8">
          6.  
             
          7.  
            <title>圣誕樹</title>
          8.  
             
          9.  
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
          10.  
             
          11.  
            <style>
          12.  
            * {
          13.  
            box-sizing: border-box;
          14.  
            }
          15.  
             
          16.  
             
          17.  
            body {
          18.  
            margin: 0;
          19.  
            height: 100vh;
          20.  
            overflow: hidden;
          21.  
            display: flex;
          22.  
            align-items: center;
          23.  
            justify-content: center;
          24.  
            background: #161616;
          25.  
            color: #c5a880;
          26.  
            font-family: sans-serif;
          27.  
            }
          28.  
             
          29.  
             
          30.  
            label {
          31.  
            display: inline-block;
          32.  
            background-color: #161616;
          33.  
            padding: 16px;
          34.  
            border-radius: 0.3rem;
          35.  
            cursor: pointer;
          36.  
            margin-top: 1rem;
          37.  
            width: 300px;
          38.  
            border-radius: 10px;
          39.  
            border: 1px solid #c5a880;
          40.  
            text-align: center;
          41.  
            }
          42.  
             
          43.  
             
          44.  
            ul {
          45.  
            list-style-type: none;
          46.  
            padding: 0;
          47.  
            margin: 0;
          48.  
            }
          49.  
             
          50.  
             
          51.  
            .btn {
          52.  
            background-color: #161616;
          53.  
            border-radius: 10px;
          54.  
            color: #c5a880;
          55.  
            border: 1px solid #c5a880;
          56.  
            padding: 16px;
          57.  
            width: 300px;
          58.  
            margin-bottom: 16px;
          59.  
            line-height: 1.5;
          60.  
            cursor: pointer;
          61.  
            }
          62.  
             
          63.  
            .separator {
          64.  
            font-weight: bold;
          65.  
            text-align: center;
          66.  
            width: 300px;
          67.  
            margin: 16px 0px;
          68.  
            color: #a07676;
          69.  
            }
          70.  
             
          71.  
             
          72.  
            .title {
          73.  
            color: #a07676;
          74.  
            font-weight: bold;
          75.  
            font-size: 1.25rem;
          76.  
            margin-bottom: 16px;
          77.  
            }
          78.  
             
          79.  
             
          80.  
            .text-loading {
          81.  
            font-size: 2rem;
          82.  
            }
          83.  
            </style>
          84.  
             
          85.  
            <script>
          86.  
            window.console = window.console || function (t) { };
          87.  
            </script>
          88.  
             
          89.  
             
          90.  
             
          91.  
            <script>
          92.  
            if (document.location.search.match(/type=embed/gi)) {
          93.  
            window.parent.postMessage("resize", "*");
          94.  
            }
          95.  
            </script>
          96.  
             
          97.  
             
          98.  
            </head>
          99.  
             
          100.  
            <body translate="no">
          101.  
            <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/build/three.min.js"></script>
          102.  
            <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/EffectComposer.js"></script>
          103.  
            <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/RenderPass.js"></script>
          104.  
            <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/ShaderPass.js"></script>
          105.  
            <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/CopyShader.js"></script>
          106.  
            <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/LuminosityHighPassShader.js"></script>
          107.  
            <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/UnrealBloomPass.js"></script>
          108.  
             
          109.  
            <div id="overlay">
          110.  
            <ul>
          111.  
            <li class="title">請選擇音樂</li>
          112.  
            <li>
          113.  
            <button class="btn" id="btnA" type="button">
          114.  
            Snowflakes Falling Down by Simon Panrucker
          115.  
            </button>
          116.  
            </li>
          117.  
            <li><button class="btn" id="btnB" type="button">This Christmas by Dott</button></li>
          118.  
            <li><button class="btn" id="btnC" type="button">No room at the inn by TRG Banks</button></li>
          119.  
            <li><button class="btn" id="btnD" type="button">Jingle Bell Swing by Mark Smeby</button></li>
          120.  
            <li class="separator">或者</li>
          121.  
            <li>
          122.  
            <input type="file" id="upload" hidden />
          123.  
            <label for="upload">Upload File</label>
          124.  
            </li>
          125.  
            </ul>
          126.  
            </div>
          127.  
             
          128.  
            <script id="rendered-js">
          129.  
            const { PI, sin, cos } = Math;
          130.  
            const TAU = 2 * PI;
          131.  
             
          132.  
            const map = (value, sMin, sMax, dMin, dMax) => {
          133.  
            return dMin + (value - sMin) / (sMax - sMin) * (dMax - dMin);
          134.  
            };
          135.  
             
          136.  
            const range = (n, m = 0) =>
          137.  
            Array(n).
          138.  
            fill(m).
          139.  
            map((i, j) => i + j);
          140.  
             
          141.  
            const rand = (max, min = 0) => min + Math.random() * (max - min);
          142.  
            const randInt = (max, min = 0) => Math.floor(min + Math.random() * (max - min));
          143.  
            const randChoise = arr => arr[randInt(arr.length)];
          144.  
            const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];
          145.  
             
          146.  
            let scene, camera, renderer, analyser;
          147.  
            let step = 0;
          148.  
            const uniforms = {
          149.  
            time: { type: "f", value: 0.0 },
          150.  
            step: { type: "f", value: 0.0 }
          151.  
            };
          152.  
             
          153.  
            const params = {
          154.  
            exposure: 1,
          155.  
            bloomStrength: 0.9,
          156.  
            bloomThreshold: 0,
          157.  
            bloomRadius: 0.5
          158.  
            };
          159.  
             
          160.  
            let composer;
          161.  
             
          162.  
            const fftSize = 2048;
          163.  
            const totalPoints = 4000;
          164.  
             
          165.  
            const listener = new THREE.AudioListener();
          166.  
             
          167.  
            const audio = new THREE.Audio(listener);
          168.  
             
          169.  
            document.querySelector("input").addEventListener("change", uploadAudio, false);
          170.  
             
          171.  
            const buttons = document.querySelectorAll(".btn");
          172.  
            buttons.forEach((button, index) =>
          173.  
            button.addEventListener("click", () => loadAudio(index)));
          174.  
             
          175.  
             
          176.  
            function init() {
          177.  
            const overlay = document.getElementById("overlay");
          178.  
            overlay.remove();
          179.  
             
          180.  
            scene = new THREE.Scene();
          181.  
            renderer = new THREE.WebGLRenderer({ antialias: true });
          182.  
            renderer.setPixelRatio(window.devicePixelRatio);
          183.  
            renderer.setSize(window.innerWidth, window.innerHeight);
          184.  
            document.body.appendChild(renderer.domElement);
          185.  
             
          186.  
            camera = new THREE.PerspectiveCamera(
          187.  
            60,
          188.  
            window.innerWidth / window.innerHeight,
          189.  
            1,
          190.  
            1000);
          191.  
             
          192.  
            camera.position.set(-0.09397456774197047, -2.5597086635726947, 24.420789670889008);
          193.  
            camera.rotation.set(0.10443543723052419, -0.003827152981119352, 0.0004011488708739715);
          194.  
             
          195.  
            const format = renderer.capabilities.isWebGL2 ?
          196.  
            THREE.RedFormat :
          197.  
            THREE.LuminanceFormat;
          198.  
             
          199.  
            uniforms.tAudioData = {
          200.  
            value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, format)
          201.  
            };
          202.  
             
          203.  
             
          204.  
            addPlane(scene, uniforms, 3000);
          205.  
            addSnow(scene, uniforms);
          206.  
             
          207.  
            range(10).map(i => {
          208.  
            addTree(scene, uniforms, totalPoints, [20, 0, -20 * i]);
          209.  
            addTree(scene, uniforms, totalPoints, [-20, 0, -20 * i]);
          210.  
            });
          211.  
             
          212.  
            const renderScene = new THREE.RenderPass(scene, camera);
          213.  
             
          214.  
            const bloomPass = new THREE.UnrealBloomPass(
          215.  
            new THREE.Vector2(window.innerWidth, window.innerHeight),
          216.  
            1.5,
          217.  
            0.4,
          218.  
            0.85);
          219.  
             
          220.  
            bloomPass.threshold = params.bloomThreshold;
          221.  
            bloomPass.strength = params.bloomStrength;
          222.  
            bloomPass.radius = params.bloomRadius;
          223.  
             
          224.  
            composer = new THREE.EffectComposer(renderer);
          225.  
            composer.addPass(renderScene);
          226.  
            composer.addPass(bloomPass);
          227.  
             
          228.  
            addListners(camera, renderer, composer);
          229.  
            animate();
          230.  
            }
          231.  
             
          232.  
            function animate(time) {
          233.  
            analyser.getFrequencyData();
          234.  
            uniforms.tAudioData.value.needsUpdate = true;
          235.  
            step = (step + 1) % 1000;
          236.  
            uniforms.time.value = time;
          237.  
            uniforms.step.value = step;
          238.  
            composer.render();
          239.  
            requestAnimationFrame(animate);
          240.  
            }
          241.  
             
          242.  
            function loadAudio(i) {
          243.  
            document.getElementById("overlay").innerHTML =
          244.  
            '<div class="text-loading">正在下載音樂,請稍等...</div>';
          245.  
            const files = [
          246.  
            "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Simon_Panrucker/Happy_Christmas_You_Guys/Simon_Panrucker_-_01_-_Snowflakes_Falling_Down.mp3",
          247.  
            "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Dott/This_Christmas/Dott_-_01_-_This_Christmas.mp3",
          248.  
            "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/TRG_Banks/TRG_Banks_Christmas_Album/TRG_Banks_-_12_-_No_room_at_the_inn.mp3",
          249.  
            "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/Mark_Smeby/En_attendant_Nol/Mark_Smeby_-_07_-_Jingle_Bell_Swing.mp3"];
          250.  
             
          251.  
            const file = files[i];
          252.  
             
          253.  
            const loader = new THREE.AudioLoader();
          254.  
            loader.load(file, function (buffer) {
          255.  
            audio.setBuffer(buffer);
          256.  
            audio.play();
          257.  
            analyser = new THREE.AudioAnalyser(audio, fftSize);
          258.  
            init();
          259.  
            });
          260.  
             
          261.  
             
          262.  
             
          263.  
             
          264.  
            }
          265.  
             
          266.  
             
          267.  
            function uploadAudio(event) {
          268.  
            document.getElementById("overlay").innerHTML =
          269.  
            '<div class="text-loading">請稍等...</div>';
          270.  
            const files = event.target.files;
          271.  
            const reader = new FileReader();
          272.  
             
          273.  
            reader.onload = function (file) {
          274.  
            var arrayBuffer = file.target.result;
          275.  
             
          276.  
            listener.context.decodeAudioData(arrayBuffer, function (audioBuffer) {
          277.  
            audio.setBuffer(audioBuffer);
          278.  
            audio.play();
          279.  
            analyser = new THREE.AudioAnalyser(audio, fftSize);
          280.  
            init();
          281.  
            });
          282.  
            };
          283.  
             
          284.  
            reader.readAsArrayBuffer(files[0]);
          285.  
            }
          286.  
             
          287.  
            function addTree(scene, uniforms, totalPoints, treePosition) {
          288.  
            const vertexShader = `
          289.  
            attribute float mIndex;
          290.  
            varying vec3 vColor;
          291.  
            varying float opacity;
          292.  
            uniform sampler2D tAudioData;
          293.  
            float norm(float value, float min, float max ){
          294.  
            return (value - min) / (max - min);
          295.  
            }
          296.  
            float lerp(float norm, float min, float max){
          297.  
            return (max - min) * norm + min;
          298.  
            }
          299.  
            float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
          300.  
            return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
          301.  
            }
          302.  
            void main() {
          303.  
            vColor = color;
          304.  
            vec3 p = position;
          305.  
            vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
          306.  
            float amplitude = texture2D( tAudioData, vec2( mIndex, 0.1 ) ).r;
          307.  
            float amplitudeClamped = clamp(amplitude-0.4,0.0, 0.6 );
          308.  
            float sizeMapped = map(amplitudeClamped, 0.0, 0.6, 1.0, 20.0);
          309.  
            opacity = map(mvPosition.z , -200.0, 15.0, 0.0, 1.0);
          310.  
            gl_PointSize = sizeMapped * ( 100.0 / -mvPosition.z );
          311.  
            gl_Position = projectionMatrix * mvPosition;
          312.  
            }
          313.  
            `;
          314.  
            const fragmentShader = `
          315.  
            varying vec3 vColor;
          316.  
            varying float opacity;
          317.  
            uniform sampler2D pointTexture;
          318.  
            void main() {
          319.  
            gl_FragColor = vec4( vColor, opacity );
          320.  
            gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
          321.  
            }
          322.  
            `;
          323.  
            const shaderMaterial = new THREE.ShaderMaterial({
          324.  
            uniforms: {
          325.  
            ...uniforms,
          326.  
            pointTexture: {
          327.  
            value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`)
          328.  
            }
          329.  
            },
          330.  
             
          331.  
             
          332.  
            vertexShader,
          333.  
            fragmentShader,
          334.  
            blending: THREE.AdditiveBlending,
          335.  
            depthTest: false,
          336.  
            transparent: true,
          337.  
            vertexColors: true
          338.  
            });
          339.  
             
          340.  
             
          341.  
            const geometry = new THREE.BufferGeometry();
          342.  
            const positions = [];
          343.  
            const colors = [];
          344.  
            const sizes = [];
          345.  
            const phases = [];
          346.  
            const mIndexs = [];
          347.  
             
          348.  
            const color = new THREE.Color();
          349.  
             
          350.  
            for (let i = 0; i < totalPoints; i++) {
          351.  
            const t = Math.random();
          352.  
            const y = map(t, 0, 1, -8, 10);
          353.  
            const ang = map(t, 0, 1, 0, 6 * TAU) + TAU / 2 * (i % 2);
          354.  
            const [z, x] = polar(ang, map(t, 0, 1, 5, 0));
          355.  
             
          356.  
            const modifier = map(t, 0, 1, 1, 0);
          357.  
            positions.push(x + rand(-0.3 * modifier, 0.3 * modifier));
          358.  
            positions.push(y + rand(-0.3 * modifier, 0.3 * modifier));
          359.  
            positions.push(z + rand(-0.3 * modifier, 0.3 * modifier));
          360.  
             
          361.  
            color.setHSL(map(i, 0, totalPoints, 1.0, 0.0), 1.0, 0.5);
          362.  
             
          363.  
            colors.push(color.r, color.g, color.b);
          364.  
            phases.push(rand(1000));
          365.  
            sizes.push(1);
          366.  
            const mIndex = map(i, 0, totalPoints, 1.0, 0.0);
          367.  
            mIndexs.push(mIndex);
          368.  
            }
          369.  
             
          370.  
            geometry.setAttribute(
          371.  
            "position",
          372.  
            new THREE.Float32BufferAttribute(positions, 3).setUsage(
          373.  
            THREE.DynamicDrawUsage));
          374.  
             
          375.  
             
          376.  
            geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
          377.  
            geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
          378.  
            geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
          379.  
            geometry.setAttribute("mIndex", new THREE.Float32BufferAttribute(mIndexs, 1));
          380.  
             
          381.  
            const tree = new THREE.Points(geometry, shaderMaterial);
          382.  
             
          383.  
            const [px, py, pz] = treePosition;
          384.  
             
          385.  
            tree.position.x = px;
          386.  
            tree.position.y = py;
          387.  
            tree.position.z = pz;
          388.  
             
          389.  
            scene.add(tree);
          390.  
            }
          391.  
             
          392.  
            function addSnow(scene, uniforms) {
          393.  
            const vertexShader = `
          394.  
            attribute float size;
          395.  
            attribute float phase;
          396.  
            attribute float phaseSecondary;
          397.  
            varying vec3 vColor;
          398.  
            varying float opacity;
          399.  
            uniform float time;
          400.  
            uniform float step;
          401.  
            float norm(float value, float min, float max ){
          402.  
            return (value - min) / (max - min);
          403.  
            }
          404.  
            float lerp(float norm, float min, float max){
          405.  
            return (max - min) * norm + min;
          406.  
            }
          407.  
            float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
          408.  
            return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
          409.  
            }
          410.  
            void main() {
          411.  
            float t = time* 0.0006;
          412.  
            vColor = color;
          413.  
            vec3 p = position;
          414.  
            p.y = map(mod(phase+step, 1000.0), 0.0, 1000.0, 25.0, -8.0);
          415.  
            p.x += sin(t+phase);
          416.  
            p.z += sin(t+phaseSecondary);
          417.  
            opacity = map(p.z, -150.0, 15.0, 0.0, 1.0);
          418.  
            vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
          419.  
            gl_PointSize = size * ( 100.0 / -mvPosition.z );
          420.  
            gl_Position = projectionMatrix * mvPosition;
          421.  
            }
          422.  
            `;
          423.  
             
          424.  
            const fragmentShader = `
          425.  
            uniform sampler2D pointTexture;
          426.  
            varying vec3 vColor;
          427.  
            varying float opacity;
          428.  
            void main() {
          429.  
            gl_FragColor = vec4( vColor, opacity );
          430.  
            gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
          431.  
            }
          432.  
            `;
          433.  
            function createSnowSet(sprite) {
          434.  
            const totalPoints = 300;
          435.  
            const shaderMaterial = new THREE.ShaderMaterial({
          436.  
            uniforms: {
          437.  
            ...uniforms,
          438.  
            pointTexture: {
          439.  
            value: new THREE.TextureLoader().load(sprite)
          440.  
            }
          441.  
            },
          442.  
             
          443.  
             
          444.  
            vertexShader,
          445.  
            fragmentShader,
          446.  
            blending: THREE.AdditiveBlending,
          447.  
            depthTest: false,
          448.  
            transparent: true,
          449.  
            vertexColors: true
          450.  
            });
          451.  
             
          452.  
             
          453.  
            const geometry = new THREE.BufferGeometry();
          454.  
            const positions = [];
          455.  
            const colors = [];
          456.  
            const sizes = [];
          457.  
            const phases = [];
          458.  
            const phaseSecondaries = [];
          459.  
             
          460.  
            const color = new THREE.Color();
          461.  
             
          462.  
            for (let i = 0; i < totalPoints; i++) {
          463.  
            const [x, y, z] = [rand(25, -25), 0, rand(15, -150)];
          464.  
            positions.push(x);
          465.  
            positions.push(y);
          466.  
            positions.push(z);
          467.  
             
          468.  
            color.set(randChoise(["#f1d4d4", "#f1f6f9", "#eeeeee", "#f1f1e8"]));
          469.  
             
          470.  
            colors.push(color.r, color.g, color.b);
          471.  
            phases.push(rand(1000));
          472.  
            phaseSecondaries.push(rand(1000));
          473.  
            sizes.push(rand(4, 2));
          474.  
            }
          475.  
             
          476.  
            geometry.setAttribute(
          477.  
            "position",
          478.  
            new THREE.Float32BufferAttribute(positions, 3));
          479.  
             
          480.  
            geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
          481.  
            geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
          482.  
            geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
          483.  
            geometry.setAttribute(
          484.  
            "phaseSecondary",
          485.  
            new THREE.Float32BufferAttribute(phaseSecondaries, 1));
          486.  
             
          487.  
             
          488.  
            const mesh = new THREE.Points(geometry, shaderMaterial);
          489.  
             
          490.  
            scene.add(mesh);
          491.  
            }
          492.  
            const sprites = [
          493.  
            "https://assets.codepen.io/3685267/snowflake1.png",
          494.  
            "https://assets.codepen.io/3685267/snowflake2.png",
          495.  
            "https://assets.codepen.io/3685267/snowflake3.png",
          496.  
            "https://assets.codepen.io/3685267/snowflake4.png",
          497.  
            "https://assets.codepen.io/3685267/snowflake5.png"];
          498.  
             
          499.  
            sprites.forEach(sprite => {
          500.  
            createSnowSet(sprite);
          501.  
            });
          502.  
            }
          503.  
             
          504.  
            function addPlane(scene, uniforms, totalPoints) {
          505.  
            const vertexShader = `
          506.  
            attribute float size;
          507.  
            attribute vec3 customColor;
          508.  
            varying vec3 vColor;
          509.  
            void main() {
          510.  
            vColor = customColor;
          511.  
            vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
          512.  
            gl_PointSize = size * ( 300.0 / -mvPosition.z );
          513.  
            gl_Position = projectionMatrix * mvPosition;
          514.  
            }
          515.  
            `;
          516.  
            const fragmentShader = `
          517.  
            uniform vec3 color;
          518.  
            uniform sampler2D pointTexture;
          519.  
            varying vec3 vColor;
          520.  
            void main() {
          521.  
            gl_FragColor = vec4( vColor, 1.0 );
          522.  
            gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
          523.  
            }
          524.  
            `;
          525.  
            const shaderMaterial = new THREE.ShaderMaterial({
          526.  
            uniforms: {
          527.  
            ...uniforms,
          528.  
            pointTexture: {
          529.  
            value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`)
          530.  
            }
          531.  
            },
          532.  
             
          533.  
             
          534.  
            vertexShader,
          535.  
            fragmentShader,
          536.  
            blending: THREE.AdditiveBlending,
          537.  
            depthTest: false,
          538.  
            transparent: true,
          539.  
            vertexColors: true
          540.  
            });
          541.  
             
          542.  
             
          543.  
            const geometry = new THREE.BufferGeometry();
          544.  
            const positions = [];
          545.  
            const colors = [];
          546.  
            const sizes = [];
          547.  
             
          548.  
            const color = new THREE.Color();
          549.  
             
          550.  
            for (let i = 0; i < totalPoints; i++) {
          551.  
            const [x, y, z] = [rand(-25, 25), 0, rand(-150, 15)];
          552.  
            positions.push(x);
          553.  
            positions.push(y);
          554.  
            positions.push(z);
          555.  
             
          556.  
            color.set(randChoise(["#93abd3", "#f2f4c0", "#9ddfd3"]));
          557.  
             
          558.  
            colors.push(color.r, color.g, color.b);
          559.  
            sizes.push(1);
          560.  
            }
          561.  
             
          562.  
            geometry.setAttribute(
          563.  
            "position",
          564.  
            new THREE.Float32BufferAttribute(positions, 3).setUsage(
          565.  
            THREE.DynamicDrawUsage));
          566.  
             
          567.  
             
          568.  
            geometry.setAttribute(
          569.  
            "customColor",
          570.  
            new THREE.Float32BufferAttribute(colors, 3));
          571.  
             
          572.  
            geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
          573.  
             
          574.  
            const plane = new THREE.Points(geometry, shaderMaterial);
          575.  
             
          576.  
            plane.position.y = -8;
          577.  
            scene.add(plane);
          578.  
            }
          579.  
             
          580.  
            function addListners(camera, renderer, composer) {
          581.  
            document.addEventListener("keydown", e => {
          582.  
            const { x, y, z } = camera.position;
          583.  
            console.log(`camera.position.set(${x},${y},${z})`);
          584.  
            const { x: a, y: b, z: c } = camera.rotation;
          585.  
            console.log(`camera.rotation.set(${a},$,${c})`);
          586.  
            });
          587.  
             
          588.  
            window.addEventListener(
          589.  
            "resize",
          590.  
            () => {
          591.  
            const width = window.innerWidth;
          592.  
            const height = window.innerHeight;
          593.  
             
          594.  
            camera.aspect = width / height;
          595.  
            camera.updateProjectionMatrix();
          596.  
             
          597.  
            renderer.setSize(width, height);
          598.  
            composer.setSize(width, height);
          599.  
            },
          600.  
            false);
          601.  
             
          602.  
            }
          603.  
            </script>
          604.  
             
          605.  
            </body>
          606.  
             
          607.  
            </html>
           

          WebSocket:實現實時雙向數據傳輸的Web通信協議

          前端達人

           

          前言

          在當今互聯網時代,實時通信已成為很多應用的需求。為了滿足這種需求,WebSocket協議被設計出來。WebSocket是一種基于TCP議的全雙工通信協議,通過WebSocket,Web應用程序可以與服務器建立持久的連接,實現實時雙向數據輸,提供極低的延遲和高效的數據傳輸。


          WebSocket原理

          • HTTP請求-響應協議

          在理解WebSocket原理之前,我們需要了解HTTP請求-響應協議。HTTP是一種無狀態的請求-響應協議,客戶端通過發送HTTP請求到服務器,服務器接收并處理請求,并返回HTTP響應給客戶端。但是,在傳統的HTTP協議中,客戶端只能發送請求,而服務器只能通過響應來處理客戶端的請求。

          • WebSocket協議

          WebSocket協議是在HTTP協議的基礎上進行擴展的。在建立WebSocket連接時,客戶端首先發送一個HTTP請求到服務器,并將Upgrade頭部字段設置為"websocket",表示希望升級到WebSocket協議。服務器接收到這個請求后,如果支持WebSocket協議,會返回一個狀態碼101 Switching Protocols的HTTP響應,并通過Upgrade頭部字段將連接升級為WebSocket連接。

          升級完成后,客戶端和服務器之間的通信不再遵循HTTP請求-響應模式,而是通過WebSocket協議進行雙向的實時通信。客戶端和服務器可以直接發送消息給對方,不需要等待對方的請求。


          如何使用WebSocket

          建立WebSocket連接:

          要建立WebSocket連接,需要在客戶端和服務器之間進行系列的握手操作。下面是詳細的代碼教程,示了如何在Web應用程序中建立WebSocket連接。

          在戶端(JavaScript):

          // 創建WebSocket對象并指定服務器地址
          var socket = new WebSocket("ws://example.com/socket");
          
          

          // 監聽連接建立事件
          socket.onopen = function() {
          console.log("WebSocket連接已建立");
          // 在連接建立后,可以發送消息到服務器
          socket.send("Hello Server!");
          };

          
          

          // 監聽接收到服務器發送的消息
          socket.onmessage = function(event) {
          var message = event.data;
          console.log("接收到服務器發送的消息:" + message);
          };

          
          

          // 監聽連接關閉事件
          socket.onclose = function(event) {
          console.log("WebSocket連接已關閉");
          };

          
          

          // 監聽連接錯誤事件
          socket.onerror = function(event) {
          console.error("WebSocket連接錯誤:" + event};

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24

          在服務器端(示例使用Node.js):

          const WebSocket = require("ws");
          
          

          // 創建WebSocket服務器
          const wss = new WebSocket.Server({ port: 8080 });

          
          

          // 監聽連接建立事件
          wss.on("connection", function(socket) {
          console.log("WebSocket連接已建立");

          
          

          // 監聽接收到客戶端發送的消息
          socket.on("message", function(message) {
          console.log("接收到戶端發送的消息:" + message);

          
          
          <span class="token comment">// 向客戶端發送消息</span>
          socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">"Hello Client!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          
          
          

          });

          
          

          // 監聽連接關閉事件
          socket.on("close", function() {
          console.log("WebSocket連接已關閉");
          });
          });

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22

          在以上代碼中,客戶端通過創建WebSocket對象,并指定服務器地址"ws://example.com/socket"來建立WebSocket連接。同時,客戶端通過監聽onopen事件,可以在連接建立后發送消息到服務器。服務器端使用WebSocket.Server類創建WebSocket服務器,并監聽"connection事件來處理連接建立后的操作。服務器端通過socket.on(“message”)來監聽接收到客戶端發送的消息,并通過socket.send()向客戶端發送消息。

          數據傳輸:

          建立WebSocket連接后,客戶端和服務器可以通過WebSocket對象進行雙向的實時數據傳輸。下面是一個示例代碼,演示了如何在客戶端和服務器之間進行數據傳輸。

          在客戶端(JavaScript):

          // 發送消息到服務器
          socket.send("Hello Server!");
          
          

          // 監聽接收到服務器發送的消息
          socket.onmessage = function(event) {
          var message = event.data;
          console.log("接收到服務器發送的消息:" + message);
          };

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8

          在服務器端(示例使用Node.js):

          // 向客戶端發送消息
          socket.send("Hello Client!");
          
          

          // 監聽接收到客戶端發送的消息
          socket.on("message", function(message) {
          console.log("接收到客戶端發送的消息:" + message);
          });

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          在以上代碼中,客戶端通過調用socket.send()方法將消息發送到服務器,服務器通過socket.send()方法將消息發送到客戶端??蛻舳送ㄟ^監聽socket.onmessage事件來接收服務器發送的消息,服務器通過監聽socket.on("message")事件來接收客戶端發送的消息。

          通過以上代碼示例,你可以詳細了解如何使用WebSocket建立連接并進行數據傳輸。請注意,示例代碼中使用的服務器地址和端口號需要根據實際情況進行修改。同時,你還可以在具體應用中根據需要使用WebSocket的其他方法和事件來實現更復雜的功能。


          WebSocket的真實使用場景

          即時通訊:

          WebSocket非常適合用于即時通訊應用,因為它能夠實現實時雙向通信。以下是一個簡單的即時聊天應用的代碼教程。

          在客戶端(JavaScript):

          // 創建WebSocket對象并指定服務器地址
          var socket = new WebSocket("ws://example.com/socket");
          
          

          // 監聽連接建立事件
          socket.onopen = function() {
          console.log("WebSocket連接已建立");

          
          

          // 監聽文本框輸入,按下Enter鍵時發送消息
          var input = document.getElementById("input");
          input.addEventListener("keyup", function(event) {
          if (event.keyCode === 13) {
          var message = input.value;
          socket.send(message);
          input.value = "";
          }
          });
          };

          
          

          // 監聽接收到服務器發送的消息
          socket.onmessage = function(event) {
          var message = event.data;
          console.log("接收到服務器發送的消息:" + message);

          
          

          // 將接收到的消息顯示在聊天窗口中
          var chatWindow = document.getElementById("chatWindow");
          chatWindow.innerHTML += "<p>" + message + "</p>";
          };

          
          

          // 監聽連接關閉事件
          socket.onclose = function(event) {
          console.log("WebSocket連接已關閉");
          };

          
          

          // 監聽連接錯誤事件
          socket.onerror = function(event) {
          console.error("WebSocket連接錯誤:" + event};

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36

          在服務器端(示例使用Node.js):

          const WebSocket = require("ws");
          
          

          // 創建WebSocket服務器
          const wss = new WebSocket.Server({ port: 8080 });

          
          

          // 監聽連接建立事件
          wss.on("connection", function(socket) {
          console.log("WebSocket連接已建立");

          
          

          // 監聽接收到客戶端發送的消息
          socket.on("message", function(message) {
          console.log("接收到客戶端發送的消息:" + message);

          
          
          <span class="token comment">// 向所有連接的客戶端發送消息</span>
          wss<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">client</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            client<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          
          
          

          });

          
          

          // 監聽連接關閉事件
          socket.on("close", function() {
          console.log("WebSocket連接已關閉");
          });
          });

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24

          在上述代碼中,客戶端通過創建WebSocket對象連接到服務器。輸入框中的文本框用于錄入要發送的消息,按下Enter鍵時會將消息發送給服務器。服務器接收到消息后,通過遍歷所有連接的客戶端,向每個客戶端發送消息。

          這樣,多個客戶端就可以實時地進行聊天,并且所有的消息都會實時地在各個客戶端之間同步顯示。

          多人協作:

          WebSocket還可用于多人協作應用,讓多個用戶可以實時地協同編輯文檔或畫布。以下是一個簡單的代碼教程。

          在客戶端(JavaScript):

          // 創建WebSocket對象并指定服務器地址
          var socket = new WebSocket("ws://example.com/socket");
          
          

          // 監聽連接建立事件
          socket.onopen = function() {
          console.log("WebSocket連接已建立");

          
          

          // 監聽文本框輸入,按下Enter鍵時發送繪畫指令
          var canvas = document.getElementById("canvas");
          canvas.addEventListener("mousedown", function(event) {
          // 繪畫指令的數據格式可以自定義,這里使用了簡單的示例
          var instruction = {
          type: "draw",
          position: {
          x: event.clientX,
          y: event.clientY
          }
          };
          socket.send(JSON.stringify(instruction));
          });
          };

          
          

          // 監聽接收到服務器發送的消息
          socket.onmessage = function(event) {
          var message = JSON.parse(event.data);
          console.log("接收到服務器發送的消息:" + message);

          
          

          // 根據消息執行相應的操作,示例中處理了繪畫指令
          if (message.type === "draw") {
          var canvas = document.getElementById("canvas");
          var ctx = canvas.getContext("2d");
          ctx.beginPath();
          ctx.arc(message.position.x, message.position.y, 5, 0, 2 * Math.PI);
          ctx.fill();
          }
          };

          
          

          // 監聽連接關閉事件
          socket.onclose = function(event) {
          console.log("WebSocket連接已關閉");
          };

          
          

          // 監聽連接錯誤事件
          socket.onerror = function(event) {
          console.error("WebSocket連接錯誤:" + event};

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45

          在服務器端(示例使用Node.js):

          const WebSocket = require("ws");
          
          

          // 創建WebSocket服務器
          const wss = new WebSocket.Server({ port: 8080 });

          
          

          // 監聽連接建立事件
          wss.on("connection", function(socket) {
          console.log("WebSocket連接已建立");

          
          

          // 監聽接收到客戶端發送的消息
          socket.on("message", function(message) {
          console.log("接收到客戶端發送的消息:" + message);

          
          
          <span class="token comment">// 向所有連接的客戶端發送消息</span>
          wss<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">client</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            client<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          
          
          

          });

          
          

          // 監聽連接關閉事件
          socket.on("close", function() {
          console.log("WebSocket連接已關閉");
          });
          });

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24

          在上述代碼中,客戶端通過創建WebSocket對象連接到服務器。當鼠標在畫布上按下時,將繪畫指令發送給服務器。服務器接收到繪畫指令后,將指令廣播給所有連接的客戶端,并在各個客戶端上進行繪畫操作。

          這樣,多個用戶就可以實時地協同編輯同一個畫布或文檔,所有的繪畫指令都會即時同步在各個客戶端之間。

          實時數據更新:

          WebSocket還可以用于實時數據更新應用,例如股票交易應用中的實時股票價格更新。以下是一個簡單的代碼教程。

          在客戶端(JavaScript):

          // 創建WebSocket對象并指定服務器地址
          var socket = new WebSocket("鏈接");
          
          

          // 監聽連接建立事件
          socket.onopen = function() {
          console.log("WebSocket連接已建立");
          };

          
          

          // 監聽接收到服務器發送的消息
          socket.onmessage = function(event) {
          var message = JSON.parse(event.data);
          console.log("接收到服務器發送的消息:" + message);

          
          

          // 對接收到的實時數據進行處理
          var stockPriceElement = document.getElementById("stockPrice");
          stockPriceElement.innerText = message.price;
          };

          
          

          // 監聽連接關閉事件
          socket.onclose = function(event) {
          console.log("WebSocket連接已關閉");
          };

          
          

          // 監聽連接錯誤事件
          socket.onerror = function(event) {
          console.error("WebSocket連接錯誤:" + event};

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26

          在服務器端(示例使用Node.js):

          const WebSocket = require("ws");
          
          

          // 創建WebSocket服務器
          const wss = new WebSocket.Server({ port: 8080 });

          
          

          // 模擬實時股票價格更新
          setInterval(function() {
          var stockPrice = Math.random() * 100;

          
          

          // 向所有連接的客戶端發送實時數據
          wss.clients.forEach(function(client) {
          var data = {
          price: stockPrice
          };
          client.send(JSON.stringify(data));
          });
          }, 2000);

          
          

          // 監聽連接建立事件
          wss.on("connection", function(socket) {
          console.log("WebSocket連接已建立");

          
          

          // 初始化發送實時數據
          var stockPrice = Math.random() * 100;
          var data = {
          price: stockPrice
          };
          socket.send(JSON.stringify(data));

          
          

          // 監聽連接關閉事件
          socket.on("close", function() {
          console.log("WebSocket連接已關閉");
          });
          });

           

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34

          在上述代碼中,客戶端通過創建WebSocket對象連接服務器。服務器使用setInterval函數模擬實時股票價格的更新,并將更新的數據發送給所有連接的客戶端??蛻舳吮O聽接收到服務器發送的消息,并處理接收到的實時數據。

          這樣,在股票交易應用中,多個用戶可以實時地接收和顯示股票價格的更新信息。包括打游戲的時候,隊友之間互相溝通,打字交流,或者走位,放技能等等,都是即時的。


          WebSocket的優勢與局限性

          • WebSocket的優勢:
          • 雙向實時通信:WebSocket提供了雙向的實時信能力,客戶端和服務器可以通過該協議進行雙向數據傳輸,實時反饋更新信息,實現即時通訊、實時數據推送等功能。

          • 較低的延遲:與傳統的HTTP請求相比,WebSocket降低了通信的開銷,減少了傳輸和處理數據的延遲,因此可以更快進行實時數據傳輸。

          • 更高的性能:由于WebSocket使用較少的頭部信息和更有效的消息傳輸格式,因此在相同帶寬下可以傳輸更多的數據,提高了性能和效率。

          • 廣泛的瀏覽器支持:WebSocket是HTML5的一部分,并且得到了大多數現代瀏覽器的支持,因此它可以在各種平臺和設備上使用。

          • 連接保持:與傳統的HTTP請求不同,WebSocket連接保持在建立之后,雙方可以隨時進行數據傳輸,避免了不必要的連接和斷開操作。

          • WebSocket的局限性:
          • 兼容性問題:雖然現代瀏覽器廣泛支持WebSocket,但在某些舊版本或特定設備上可能存在兼容性問題。為了兼容性,可以使用輪訓技術(如長輪詢)作為備選方案。

          • 部署和維護復雜性:WebSocket服務器的設置和配置可能比傳統的Web服務器復雜一些,需要專門的服務器環境和配置。

          • 安全性問題:由于WebSocket是在HTTP協議的基礎上建立的,它們共享相同的安全風險,例如跨站點腳本(XSS)和跨站請求偽造(CSRF)。因此,在使用WebSocket時需要考慮到安全性,并采取適當的安全措施。

          • 擴展問題:WebSocket協議還不支持像HTTP/2那樣的一些高級特性,例如頭部壓縮和流量控制。在某些特殊情況下,可能需要通過其他方式實現這些功能。

          盡管WebSocket具有上述局限性,但它仍然是實時通訊、實時數據傳輸和實時協作等場景下的首選協議,因為它具備了雙向實時通信和較低延遲等一系列的優勢。在開發時,需要根據具體需求和限制,綜合考慮使用WebSocket的適用性。


          結論

          WebSocket是一種能夠提供雙向實時通信的協議,適用于需要實時數據傳輸和雙向通信的場景。它具有較低的延遲、更高的性和廣泛的瀏覽器持等優勢,能夠實現即時通訊、多人協和實時數據更新等功能。

          然而,WebSocket也存在兼容性、部署和維護復雜性、安全性問題以及缺乏一些高級特性等局限性。在開發時,需要仔細考慮具體需求和限制,并必要時采取適當的解決方案。

          總的來說,WebSocket在實時通信和實時數據傳輸方面具有明顯的優勢,是構建現代Web應用的重要工具之一。

          藍藍設計(www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的大數據可視化界面設計、B端界面設計、桌面端界面設計、APP界面設計、圖標定制、用戶體驗設計、交互設計、UI咨詢、高端網站設計、平面設計,以及相關的軟件開發服務,咨詢電話:01063334945。

          關鍵詞:UI咨詢UI設計服務公司、軟件界面設計公司、界面設計公司、UI設計公司、UI交互設計公司數據可視化設計公司、用戶體驗公司高端網站設計公司

          銀行金融軟件UI界面設計、能源及監控軟件UI界面設計氣象行業UI界面設計、軌道交通界面設計、地理信息系統GIS UI界面設計航天軍工軟件UI界面設計、醫療行業軟件UI界面設計、教育行業軟件UI界面設計、企業信息化UI界面設計、軟件qt開發軟件wpf開發、軟件vue開發

          Vue2 watch監聽props的值

          前端達人

          再次遇到監聽子組件收到父組件傳過來的值,如果這個值變化,頁面中的值發現是不會跟著同步變化的。所以監聽props中的值,一直監聽。

           

          代碼:

           
          1.  
            props: {
          2.  
            start:{
          3.  
            type: String,
          4.  
            },
          5.  
            end:{
          6.  
            type: String,
          7.  
            }
          8.  
            },
           

           

           
          1.  
            computed:{
          2.  
            myStart:function(){
          3.  
            return this.start
          4.  
            },
          5.  
            myEnd:function(){
          6.  
            return this.end
          7.  
            }
          8.  
            },
          9.  
            watch: {
          10.  
            myStart:function(newVal){
          11.  
            if(newVal){
          12.  
            this.startTime=newVal
          13.  
            }
          14.  
            },
          15.  
            myEnd:function(newVal){
          16.  
            if(newVal){
          17.  
            this.endTime=newVal
          18.  
            }
          19.  
            },
          20.  

          藍藍設計(www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的大數據可視化界面設計B端界面設計、桌面端界面設計、APP界面設計、圖標定制、用戶體驗設計、交互設計、UI咨詢、高端網站設計、平面設計,以及相關的軟件開發服務,咨詢電話:01063334945。

          關鍵詞:UI咨詢、UI設計服務公司軟件界面設計公司、界面設計公司、UI設計公司、UI交互設計公司、數據可視化設計公司用戶體驗公司、高端網站設計公司

          銀行金融軟件UI界面設計能源及監控軟件UI界面設計、氣象行業UI界面設計軌道交通界面設計、地理信息系統GIS UI界面設計、航天軍工軟件UI界面設計、醫療行業軟件UI界面設計教育行業軟件UI界面設計、企業信息化UI界面設計、軟件qt開發軟件wpf開發、軟件vue開發

          什么是前端安全性(front-end security)?列舉一些前端安全性的最佳實踐

          前端達人

          前端入門之旅:探索Web開發的奇妙世界 歡迎來到前端入門之旅!感興趣的可以訂閱本專欄哦!這個專欄是為那些對Web開發感興趣、剛剛踏入前端領域的朋友們量身打造的。無論你是完全的新手還是有一些基礎的開發者,這里都將為你提供一個系統而又親切的學習平臺。在這個專欄中,我們將以問答形式每天更新,為大家呈現精選的前端知識點和常見問題解答。通過問答形式,我們希望能夠更直接地回應讀者們對于前端技術方面的疑問,并且幫助大家逐步建立起一個扎實的基礎。無論是HTML、CSS、JavaScript還是各種常用框架和工具,我們將深入淺出地解釋概念,并提供實際案例和練習來鞏固所學內容。同時,我們也會分享一些實用技巧和最佳實踐,幫助你更好地理解并運用前端開發中的各種技術。

          無論你是尋找職業轉型、提升技能還是滿足個人興趣,我們都將全力以赴,為你提供最優質的學習資源和支持。讓我們一起探索Web開發的奇妙世界吧!加入前端入門之旅,成為一名出色的前端開發者! 讓我們啟航前端之旅?。?!


          前端安全性概述及最佳實踐

          前端安全性是指在前端開發中采取的一系列措施,旨在保護應用程序、用戶數據以及用戶隱私免受各種安全威脅。以下是一些前端安全性的最佳實踐:

          1. HTTPS 使用:

            • 使用HTTPS協議確保數據在傳輸過程中的加密,防止中間人攻擊。
          2. 內容安全策略(CSP):

            • 使用CSP來限制瀏覽器加載頁面中的資源,防止惡意腳本注入。
          3. 跨站腳本攻擊(XSS)防護:

            • 對用戶輸入和動態生成的內容進行合適的轉義或編碼。
            • 使用HTTP Only 標記來防止腳本操作 cookie。
          4. 跨站請求偽造(CSRF)防護:

            • 使用合適的令牌(CSRF Token)來驗證請求的合法性。
          5. 安全的跨域資源共享(CORS)配置:

            • 限制允許訪問資源的域,防止不受信任的域發起請求。
          6. 安全的第三方庫和框架:

            • 使用官方版本的庫和框架,避免使用已知的有安全漏洞的版本。
          7. 安全的存儲和傳輸:

            • 避免在前端存儲敏感信息,如密碼,而應交由后端進行處理。
            • 在數據傳輸時使用加密算法,確保數據在傳輸過程中的保密性。
          8. 用戶身份驗證和授權:

            • 使用安全的身份驗證方法,如OAuth或OpenID Connect。
            • 僅在有必要的情況下授予用戶特定的權限。
          9. 不使用過期或不安全的特性:

            • 避免使用已經過時或不再維護的前端框架和庫。
            • 避免使用不安全的瀏覽器特性,如棄用的插件。
          10. 前端路由安全:

            • 使用前端路由時,確保路由的訪問權限得到合理管理,防止越權訪問。
          11. 監測和報告安全事件:

            • 集成日志記錄和監控機制,及時發現異常行為。
            • 實現安全事件報告,以便及時采取措施應對攻擊。
          12. 教育和培訓:

            • 對開發團隊進行安全性培訓,提高對潛在威脅的認識。
            • 定期進行代碼審查,確保代碼符合最佳安全實踐。
          13. 安全頭部的使用:

            • 使用HTTP頭部來加強安全性,如Strict-Transport-Security(HSTS)。
          14. 定期進行安全性測試:

            • 進行定期的安全性測試,包括靜態代碼分析和滲透測試,以確保發現和修復潛在的安全漏洞。

          這些最佳實踐有助于構建更加安全、可靠的前端應用程序,減少潛在的攻擊風險。前端安全性是一個不斷演變的領域,開發者應該時刻關注新的安全威脅和最佳實踐。


           

          本專欄適用讀者比較廣泛,適用于前端初學者;或者沒有學過前端對前端有興趣的伙伴,亦或者是后端同學想在面試過程中能夠更好的展示自己拓展一些前端小知識點,所以如果你具備了前端的基礎跟著本專欄學習,也是可以很大程度幫助你查漏補缺,由于博主本人是自己再做內容輸出,如果文中出現有瑕疵的地方各位可以通過主頁的左側聯系我,我們一起進步,與此同時也推薦大家幾份專欄,有興趣的伙伴可以訂閱一下:除了下方的專欄外大家也可以到我的主頁能看到其他的專欄;

          前端小游戲(免費)這份專欄將帶你進入一個充滿創意和樂趣的世界,通過利用HTML、CSS和JavaScript的基礎知識,我們將一起搭建各種有趣的頁面小游戲。無論你是初學者還是有一些前端開發經驗,這個專欄都適合你。我們會從最基礎的知識開始,循序漸進地引導你掌握構建頁面游戲所需的技能。通過實際案例和練習,你將學會如何運用HTML來構建頁面結構,使用CSS來美化游戲界面,并利用JavaScript為游戲添加交互和動態效果。在這個專欄中,我們將涵蓋各種類型的小游戲,包括迷宮游戲、打磚塊、貪吃蛇、掃雷、計算器、飛機大戰、井字游戲、拼圖、迷宮等等。每個項目都會以簡潔明了的步驟指導你完成搭建過程,并提供詳細解釋和代碼示例。同時,我們也會分享一些優化技巧和最佳實踐,幫助你提升頁面性能和用戶體驗。無論你是想尋找一個有趣的項目來鍛煉自己的前端技能,還是對頁面游戲開發感興趣,前端小游戲專欄都會成為你的最佳選擇

          Vue3通透教程【從零到一】(付費) 歡迎來到Vue3通透教程!這個專欄旨在為大家提供全面的Vue3相關技術知識。如果你有一些Vue2經驗,這個專欄都能幫助你掌握Vue3的核心概念和使用方法。我們將從零開始,循序漸進地引導你構建一個完整的Vue應用程序。通過實際案例和練習,你將學會如何使用Vue3的模板語法、組件化開發、狀態管理、路由等功能。我們還會介紹一些高級特性,如Composition API和Teleport等,幫助你更好地理解和應用Vue3的新特性。在這個專欄中,我們將以簡潔明了的步驟指導你完成每個項目,并提供詳細解釋和示例代碼。同時,我們也會分享一些Vue3開發中常見的問題和解決方案,幫助你克服困難并提升開發效率。無論你是想深入學習Vue3或者需要一個全面的指南來構建前端項目,Vue3通透教程專欄都會成為你不可或缺的資源。

          TypeScript入門指南(免費) 是一個旨在幫助大家快速入門并掌握TypeScript相關技術的專欄。通過簡潔明了的語言和豐富的示例代碼,我們將深入講解TypeScript的基本概念、語法和特性。無論您是初學者還是有一定經驗的開發者,都能在這里找到適合自己的學習路徑。從類型注解、接口、類等核心特性到模塊化開發、工具配置以及與常見前端框架的集成,我們將全面覆蓋各個方面。通過閱讀本專欄,您將能夠提升JavaScript代碼的可靠性和可維護性,并為自己的項目提供更好的代碼質量和開發效率。讓我們一起踏上這個精彩而富有挑戰性的TypeScript之旅吧!

           

          藍藍設計(www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的大數據可視化界面設計、B端界面設計、桌面端界面設計、APP界面設計圖標定制、用戶體驗設計、交互設計、UI咨詢、高端網站設計、平面設計,以及相關的軟件開發服務,咨詢電話:01063334945。

          關鍵詞:UI咨詢、UI設計服務公司、軟件界面設計公司、界面設計公司、UI設計公司UI交互設計公司、數據可視化設計公司用戶體驗公司、高端網站設計公司

          銀行金融軟件UI界面設計、能源及監控軟件UI界面設計、氣象行業UI界面設計軌道交通界面設計、地理信息系統GIS UI界面設計、航天軍工軟件UI界面設計、醫療行業軟件UI界面設計、教育行業軟件UI界面設計、企業信息化UI界面設計、軟件qt開發、軟件wpf開發軟件vue開發

          前端學習大綱

          前端達人

          第一階段:

          • HTML+CSS:

          HTML進階、CSS進階、div+css布局、HTML+css整站開發、

          • JavaScript基礎:

          Js基礎教程、js內置對象常用方法、常見DOM樹操作大全、ECMAscript、DOM、BOM、定時器和焦點圖。

          • JS基本特效:

          常見特效、例如:tab、導航、整頁滾動、輪播圖、JS制作幻燈片、彈出層、手風琴菜單、瀑布流布局、滾動事件、滾差視圖。

          • JS高級特征:

          正則表達式、排序算法、遞歸算法、閉包、函數節流、作用域鏈、基于距離運動框架、面向對象基礎、

          • JQuery:基礎使用

          懸著器、DOM操作、特效和動畫、方法鏈、拖拽、變形、JQueryUI組件基本使用。

          第二階段:HTML5和移動Web開發

          • HTML5:

          HTML5新語義標簽、HTML5表單、音頻和視頻、離線和本地存儲、SVG、Web Socket、Canvas.

          • CSS3:

          CSS3新選擇器、偽元素、臉色表示法、邊框、陰影、background系列屬性改變、Transition、動畫、景深和深透、3D效果制作、Velocity.js框架、元素進場、出場策略、炫酷CSS3網頁制作。

          • Bootstrap:

          響應式概念、媒體查詢、響應式網站制作、刪格系統、刪格系統原理、Bootstrap常用模板、LESS和SASS。

          • 移動Web開發:

          跨終端WEB和主流設備簡介、視口、流式布局、彈性盒子、rem、移動終端JavaScript事件、手機中常見JS效果制作、Zepto.js、手機聚劃算頁面、手機滾屏。

          第三階段:HTTP服務和AJAX編程

          • WEB服務器基礎:

          服務器基礎知識、Apache服務器和其他WEB服務器介紹、Apache服務器搭建、HTTP介紹。

          • PHP基礎:

          PHP基礎語法、使用PHP處理簡單的GET或者POST請求、

          • AJAX上篇:

          Ajax簡介和異步的概念、Ajax框架的封裝、XMLHttpRequest對象詳細介紹方法、兼容性處理方法、Ajax框架的封裝、Ajax中緩存問題、XML介紹和使用。

          • AJAX下篇:

          JSON和JSON解析、數據綁定和模板技術、JSONP、跨域技術、圖片預讀取和lazy-load技術、JQuery框架中的AjaxAPI、使用Ajax實現爆布流案例額。

          第四階段:面向對象進階

          • 面向對象終極篇:

          從內存角度到理解JS面向對象、基本類型、復雜類型、原型鏈、ES6中的面向對象、屬性讀寫權限、設置器、訪問器。

          • 面向對象三大特征:

          繼承性、多態性、封裝性、接口。

          • 設計模式:

          面向對象編程思維、單例模式、工廠模式、策略模式、觀察者模式、模板方法模式、代理模式、裝飾者模式、適配器模式、面向切面編程。

          第五階段:封裝一個屬于自己的框架

          • 框架封裝基礎:

          事件流、冒泡、捕獲、事件對象、事件框架、選擇框架。

          • 框架封裝中級:

          運動原理、單物體運動框架、多物體運動框架、運動框架面向對象封裝。

          • 框架封裝高級和補充:

          JQuery框架雛形、可擴展性、模塊化、封裝屬于傳智自己的框架。

          第六階段:模塊化組件開發

          • 面向組件編程:

          面向組件編程的方式、面向組件編程的實現原理、面向組件編程實戰、基于組件化思想開發網站應用程序。

          • 面向模塊編程:

          AMD設計規范、CMD設計規范、RequireJS,LoadJS、淘寶的SeaJS。

          第七階段:主流的流行框架

          • Web開發工作流:

          GIT/SVN、Yeoman腳手架、NPM/Bower依賴管理工具、Grunt/Gulp/Webpack。

          • MVC/MVVM/MVW框架:

          Angular.js、Backbone.js、Knockout/Ember。

          • 常用庫:

          React.js、Vue.js、Zepto.js。

          第八階段:HTML5原生移動應用開發

          • Cordova:

          WebApp/NativeApp/HybirdApp簡介、Cordova簡介、與PhoneGap之間的關系、開發環境搭建、Cordova實戰(創建項目,配置,編譯,調試,部署發布)。

          • Ionic:

          Ionic簡介和同類對比、模板項目解析、常見組件及使用、結合Angular構建APP、常見效果(下拉刷新,上拉加載,側滑導航,選項卡)。

          • React Native:

          React Native簡介、React Native環境配置、創建項目,配置,編譯,調試,部署發布、原生模塊和UI組件、原生常用API。

          • HTML5+:

          HTML5+中國產業聯盟、HTML5 Plus Runtime環境、HBuilder開發工具、MUI框架、H5+開發和部署。

          第九階段:   Node.js全棧開發:

          • 快速入門:

          Node.js發展、生態圈、Io.js、Linux/Windows/OS X環境配置、REPL環境和控制臺程序、異步編程,非阻塞I/O、模塊概念,模塊管理工具、開發流程,調試,測試。

          • 核心模塊和對象:

          全局對象global,process,console,util、事件驅動,事件發射器、加密解密,路徑操作,序列化和反序列化、文件流操作、HTTP服務端與客戶端、Socket.IO。

          • Web開發基礎:

          HTTP協議,請求響應處理過程、關系型數據庫操作和數據訪問、非關系型數據庫操作和數據訪問、原生的Node.js開發Web應用程序、Web開發工作流、Node.js開發Blog案例。

          • 快速開發框架:

          Express簡介+MVC簡介、Express常用API、Express路由模塊、Jade/Ejs模板引擎、使用Express重構Blog案例、Koa等其他常見MVC框架。

          • Node.js開發電子商務實戰:

          需求與設計、賬戶模塊注冊登錄、會員中心模塊、前臺展示模塊、購物車,訂單結算、在線客服即時通訊模塊。

          MacOS查找各Python版本的路徑

          前端達人

          MacOS自帶Python路徑為:/System/Library/Frameworks/Python.framework/Versions
          自行安裝Python路徑為:/Library/Frameworks/Python.framework/Versions/
          打開Terminal
          切換工作路徑:cd /System/Library/Frameworks/Python.framework/Versions/current/bin
          打印相對路徑Python版本:./python --version
          打印當前用戶Python版本:python --version

          如下圖可以看到,系統Python版本為2.7,當前用戶Python為3.7

           

          使用which命令查看各版本Python的文件路徑

          系統命令默認路徑/usr/bin(系統預裝的可執行文件,隨系統升級而變化)
          用戶命令默認路徑/usr/local/bin(用戶安裝的可執行文件,不隨系統升級影響)
          其中,usrUnix System Resource

          可以看到/usr/bin中有python可執行命令,其版本為2.7.18,而/usr/local/bin則沒有python,存放的是python3.7的執行命令

           

          在Mac電腦上安裝Python環境可以按照以下步驟進行操作:

          步驟1: 下載Python安裝包

          訪問Python官方網站(https://www.python.org/downloads/macos/)下載適用于Mac的Python安裝包。根據你的操作系統版本選擇合適的安裝包,通常選擇最新的穩定版本。
          在這里插入圖片描述

          步驟2: 運行安裝包

          雙擊下載的Python安裝包,會出現一個安裝向導窗口。點擊"Continue"繼續安裝。
          在這里插入圖片描述

          步驟3: 配置安裝選項

          在安裝向導窗口中,可以選擇安裝Python的位置和其他可選組件。通常建議保持默認設置,然后點擊"Install"開始安裝。

          步驟4: 輸入管理員密碼

          安裝過程中,系統可能會要求輸入管理員密碼。輸入密碼并點擊"Install Software"繼續安裝。

          步驟5: 等待安裝完成

          安裝過程可能需要一些時間,請耐心等待直到安裝完成。

          步驟6: 驗證安裝結果

          安裝完成后,打開終端應用程序(Terminal),輸入以下命令驗證Python安裝是否成功:

          python3 -V
          
          • 1

          如果成功安裝,終端會顯示Python的版本號。

           

          產品經理如何與工程師合作?我總結了4個方面?。本┧{藍UI設計公司

          周周

          在產品線或者項目組中,開發工程師絕對是最大的群體,包含前端開發、后端開發、測試等崗位。之前做交互設計師時,跟開發人員直接的溝通并不多,主要在交互設計宣講和還原度測試時有些接觸。即使有些糾纏,也會通過產品經理進行協調,溝通的難度并不大。轉崗產品經理后,主要溝通對象就變成了開發工程師。今天來聊聊我遇到過或合作過的“開發大佬”們。

          干貨!四個章節深度解析「組件」知識點|蘭亭妙微UI設計公司

          資深UI設計者

          干貨!四個章節深度解析「組件」知識點|蘭亭妙微UI設計公司


          第一章:組件的定義和基本概念
          在軟件開發領域,組件是指獨立的、可重用的軟件模塊,它們具有特定的功能和接口,可以被組合成更大的軟件系統。組件可以是軟件對象、類、庫、模塊或其他單位。它們通過定義輸入和輸出接口,以及實現特定功能來提供服務。
          組件的基本概念包括以下幾個方面:
          1.1 組件容器:組件容器是一個環境,用于加載、管理和執行組件。容器提供對組件的生命周期管理、通信和部署支持。組件容器可以是運行時環境(如操作系統、應用服務器)或特定的框架(如Java EE容器、ASP.NET容器)。
          1.2 組件接口:組件接口定義了組件對外提供的服務和合約。它包括輸入參數、輸出結果以及可能的異常。接口可以通過編程語言的接口、類、方法或其他機制來定義。
          1.3 組件協作:組件可以通過協作來完成更復雜的任務。協作可以通過組件之間的接口調用、事件觸發、消息傳遞等方式進行。協作可以實現任務的拆分、并行處理和功能擴展。
          1.4 組件復用:組件的重要特性是可復用性。組件的設計和實現應該考慮到復用的需求,使其可以在不同的上下文中被重復使用。組件復用可以提高開發效率、降低維護成本,并促進軟件系統的生態系統發展。
          第二章:組件化開發和架構模式
          2.1 組件化開發:組件化開發是一種軟件開發方法,通過將軟件系統劃分為獨立的組件來提高開發效率和質量。組件化開發促進了模塊化、可復用、可測試和可維護的代碼編寫。它還鼓勵團隊協作和并行開發。
          2.2 組件化架構模式:組件化架構模式是一種組織和管理組件的方式。常見的組件化架構模式包括面向服務架構(SOA)、微服務架構和組件協作模式等。這些架構模式通過定義組件之間的接口、通信和協議,實現了松耦合、可擴展和可替換的軟件系統。

          第三章:組件的優勢和挑戰
          3.1 組件的優勢:組件化開發具有許多優勢。首先,它提供了代碼重用和模塊化的機制,減少了開發工作量和維護成本。其次,組件可以提供標準化的接口,促進了團隊協作和模塊復用。此外,組件可以獨立測試和部署,提高了系統的可靠性和可擴展性。
          3.2 組件的挑戰:盡管組件化開發具有許多優勢,但也存在一些挑戰。首先,組件的設計和實現需要額外的工作和時間。其次,組件之間的協作和通信涉及到復雜的依賴關系和調試過程。此外,組件的版本管理和升級可能導致一些兼容性和穩定性的問題。
          第四章:組件化開發實踐和案例分析
          4.1 組件化開發實踐:組件化開發需要結合具體的技術和工具來實現。常見的組件化開發實踐包括使用面向對象編程、設計模式、依賴注入和模塊化打包工具等。此外,組件化開發還需要規范和標準來指導開發和集成。
          4.2 組件化開發案例分析:組件化開發已經在軟件開發領域得到廣泛應用。例如,Android開發中的組件化架構、Java EE中的Enterprise JavaBean、.NET中的組件模型等。這些案例提供了關于組件化開發的實踐經驗和最佳實踐。

          藍藍設計,工作室2008年開始,2011年正式成立北京蘭亭妙微科技有限公司,主創清華團隊,專注軟件和互聯網ui設計開發。擅長企業信息化管理、監控、大數據軟件UIUE咨詢和設計開發服務。立足UI,一直在學習進步。
          藍藍設計,秉承設計優秀,不斷超越的理念,誠信敬業、專業耐心的工作作風,進行設計服務創新,幫助企業進行軟件和互聯網產品的界面設計及開發升級,提供卓越的解決方案。對軟件界面用戶體驗與交互設計與實現,國際化標準和流行趨勢,進行不斷的研究和實踐,擁有豐富的解決問題經驗。

          讓用戶輸密碼的正確姿勢!簡化密碼設計的三個小秘籍

          資深UI設計者

          讓用戶輸密碼的正確姿勢!簡化密碼設計的三個小秘籍

          2023-06-28 15:50北京北京蘭亭妙微科技有限公司官方帳號

          隨著互聯網的普及和數字化時代的來臨,密碼的重要性不言而喻。然而,很多人在設計密碼時往往面臨記憶難題和安全性問題。為了幫助用戶設計更簡化且安全的密碼,本文將介紹三個小秘籍。

          一、使用密碼管理工具

          密碼管理工具是一種方便且安全的方式來管理和存儲密碼。它們通常提供加密的存儲空間,可以儲存各種賬戶的用戶名和密碼。用戶只需記住一個主密碼,就能夠訪問和管理所有其他密碼。這樣,用戶可以選擇更復雜、更安全的密碼,而不必擔心記憶的問題。此外,密碼管理工具通常還提供自動生成密碼的功能,確保密碼的隨機性和安全性。一些常見的密碼管理工具包括LastPass、1Password和Keepass等。

          二、使用短語或句子作為密碼

          傳統的密碼通常由字符、數字和特殊符號組成,很難記憶且容易被猜測。相比之下,使用短語或句子作為密碼可以更容易記住且更安全。選擇一個有意義的短語或句子,并將其轉化為密碼。例如,"ILoveToTravelTheWorld!",這個短語可以轉化為密碼"Ilv2ttw!"。這樣的密碼不僅容易記憶,而且由于包含了大小寫字母、數字和特殊符號,具備了一定的安全性。

          三、使用多因素身份驗證

          多因素身份驗證是一種提高賬戶安全性的重要方式。除了使用密碼外,多因素身份驗證要求用戶提供第二個驗證因素,如手機驗證碼、指紋識別或硬件安全密鑰等。這樣,即使密碼被泄露,黑客也無法輕易訪問賬戶。許多在線服務提供了多因素身份驗證選項,用戶應該積極開啟并使用這個功能。

          綜上所述,設計簡化且安全的密碼并不是一件困難的事情。通過使用密碼管理工具、使用短語或句子作為密碼以及使用多因素身份驗證,用戶可以更好地保護自己的賬戶安全。重要的是,用戶應該時刻保持警惕,定期更換密碼,并避免在多個賬戶中使用相同的密碼,以確保個人信息的安全。

          今日分享這篇文章是藍藍設計的原創文章,未來將會持續在平臺上分享關于設計行業的文章。此外藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,添加vx藍小助ben_lanlan,報下信息,藍小助會請您入群。同時添加藍小助我們將會為您提供優秀的設計案例和設計素材等,歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數據可視化設計公司、UI交互設計公司、高端網站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司

          js谷歌地圖 根據國家添加不同的點擊事件

          前端達人

          以下是在 JavaScript 和 Google 地圖 API 中添加點擊事件,根據國家進行不同操作的示例代碼:


          //創建地圖對象
          var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 4,
            center: {lat: 37.0902, lng: -95.7129}
          });
          
          //創建信息窗口(infowindow)
          var infowindow = new google.maps.InfoWindow();
          
          //創建一個數組來存儲標記
          var markers = [];
          
          //為每個國家添加點擊事件
          google.maps.event.addListener(map, 'click', function(event) {
            //獲取點擊位置的經緯度坐標
            var latLng = event.latLng;
          
            //使用地理編碼器(geocoder)將經緯度坐標轉換為地址信息
            var geocoder = new google.maps.Geocoder();
            geocoder.geocode({'location': latLng}, function(results, status) {
              if (status === 'OK') {
                if (results[0]) {
                  //獲取點擊位置所在的國家名稱
                  var countryName = '';
                  for (var i = 0; i < results[0].address_components.length; i++) {
                    var component = results[0].address_components[i];
                    if (component.types.indexOf('country') !== -1) {
                      countryName = component.long_name;
                      break;
                    }
                  }
          
                  //根據國家名稱執行相應操作
                  switch (countryName) {
                    case 'China':
                      alert('您點擊了中國');
                      break;
                    case 'United States':
                      alert('您點擊了美國');
                      break;
                    default:
                      alert('您點擊了' + countryName);
                  }
          
                  //創建標記并將其添加到地圖上
                  var marker = new google.maps.Marker({
                    position: latLng,
                    map: map
                  });
          
          
          
          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~ 希望得到建議咨詢、商務合作,也請與我們聯系01063334945。  分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。  藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數據可視化設計公司、UI交互設計公司、高端網站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。 

          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合