整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript 圖片橫向滾動輪播

          JavaScript 圖片橫向滾動輪播

          例1: 無縫連續滾動

          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="UTF-8">
          <title></title>
          <style type="text/css">
          *{
          margin: 0;
          padding: 0;
          list-style: none;
          }
          div{
          width: 1000px;
          height: 130px;
          margin: 100px auto;
          border: 1px solid #000;
          position: relative;
          
          overflow: hidden; /* 防止滾動的圖片溢出 */
          }
          ul{
          width: 2000px;
          position: absolute;
          left: 0;
          top: 0;
          }
          li{
          float: left;
          }
          img{
          display: block;
          }
          </style>
          </head>
          <body>
          <div>
          <ul>
          <li><img src="img/1.png"/></li>
          <li><img src="img/2.png"/></li>
          <li><img src="img/3.png"/></li>
          <li><img src="img/4.png"/></li>
          <li><img src="img/5.png"/></li>
          <!--我們在復制一套出來-->
          <li><img src="img/1.png"/></li>
          <li><img src="img/2.png"/></li>
          <li><img src="img/3.png"/></li>
          <li><img src="img/4.png"/></li>
          <li><img src="img/5.png"/></li>
          </ul>
          </div>
          
          <script type="text/javascript">
          var ul=document.getElementsByTagName("ul")[0];
          
          setInterval(function(){
              if(getStyle(ul,"left")===-1000){
              ul.style.left="0px";//執行這一行代碼需要多長時間???
              }
          
              ul.style.left=getStyle(ul,"left") - 1 + "px";
          },10)
          
          
          function getStyle(obj,attr){
              if(window.getComputedStyle){
              return parseInt(window.getComputedStyle(obj)[attr]);
              }else{
              return parseInt(obj.currentStyle[attr]);
              }
          }
          </script>
          </body>
          </html>

          圖片規格: 200px 130px

          本篇文章主要給大家介紹一下如何使用html+css完成二級橫向以及豎向菜單導航制作;菜單導航是網站建設中最常用的一塊了,基本每個網站內都會有個導航菜單,用鼠標劃過還可以有下拉子菜單。

          由上圖我們可以看出,該圖包含一個橫向導航條,然后鼠標經過橫向導航條之后,子導航顯示出來。

          1)制作頁面所用知識點

          我們這里主要用到的知識點就是列表標簽(ul、dl)的使用、浮動(float)的使用、絕對定位(absolute)及鼠標經過(hover)的效果。

          1、列表標簽ul、dl(我們使用ul、dl來創建同類型的導航元素內容,通過設置css樣式來達到圖片所示效果);

          2、浮動元素float(每個導航元素我們需要使用float:left;讓其左對齊,這里涉及到了我們之前講解的如何清除浮動的影響);

          3、絕對定位absolute(對于子導航我們要使用絕對定位來讓其浮動在上級有定位元素的下方,不占據元素空間)

          4、鼠標經過hover(使用css的鼠標經過元素(hover)效果,配合display的none(隱藏)和block(顯示)來實現子菜單的顯示與隱藏)

          具體的實現html代碼以及css代碼就如下圖所示:

          2)縱向菜單導航

          還有一個縱向菜單導航原理跟橫向的類似,只需簡單調整一下css代碼即可。

          html代碼跟橫向一樣,這里就不再貼圖,具體的實現圖片效果以及css代碼就如下圖所示:

          好了,本篇文章就給大家說到這里,大家自己動手寫一下看能不能寫出一樣的頁面效果出來,也可以找一些類似的頁面自己練習一下,有需要源碼的可以直接私信我即可。

          每日金句:每天收獲小進步,積累起來就是大進步;每天收獲小幸福,積攢起來便成大幸福。喜歡我的文章的小伙伴記得關注一下哦,每天將為你更新最新知識。

          WebRTC (Web Real-Time Communications) 是一項實時通訊技術,它允許網絡應用或者站點,在不借助中間媒介的情況下,建立瀏覽器之間點對點(Peer-to-Peer)的連接,實現視頻流和(或)音頻流或者其他任意數據的傳輸。WebRTC包含的這些標準使用戶在無需安裝任何插件或者第三方的軟件的情況下,創建點對點(Peer-to-Peer)的數據分享和電話會議成為可能。

          webRTC協議介紹

          ice

          交互式連接機構 (ICE)是一個框架,允許您的網絡瀏覽器與同行連接。有許多原因,為什么從對等A到同行B的直升連接將不起作用。它需要繞過防火墻,防止打開連接,給您一個獨特的地址,如果像大多數情況下,您的設備沒有公共 IP 地址,并通過服務器中繼數據,如果你的路由器不允許您直接與對等連接。ICE 使用 STUN 和/或 TURN 服務器來實現此目的,如下所述。

          STUN

          NAT 的會話橫向公用設施 (STUN)是一個協議,以發現您的公共地址,并確定任何限制,在你的路由器,將阻止與同行的直接連接。

          客戶端將向 Internet 上的 STUN 服務器發送請求,該服務器將回復客戶的公共地址,以及路由器 NAT 后面是否訪問客戶端。

          NAT

          網絡地址翻譯 (NAT)用于為您的設備提供公共 IP 地址。路由器將具有公共 IP 地址,連接到路由器的每個設備都將有一個私有 IP 地址。請求將從設備的私有 IP 轉換為路由器的公共 IP,并具有獨特的端口。這樣,您不需要每個設備都有獨特的公共 IP,但仍可以在互聯網上發現。

          某些路由器將限制誰可以連接到網絡上的設備。這可能意味著,即使我們有 STUN 服務器找到的公共 IP 地址,也沒有人能夠創建連接。在這種情況下,我們需要轉向轉向。

          TURN

          一些使用 NAT 的路由器采用一種稱為"對稱 NAT"的限制。這意味著路由器將只接受您以前連接過的對等的連接。

          使用 NAT 周圍的中繼進行橫向(轉)旨在通過打開與 TURN 服務器的連接并通過該服務器中繼所有信息來繞過對稱 NAT 限制。您將創建與 TURN 服務器的連接,并告訴所有對應方將數據包發送到服務器,然后轉發給服務器。這顯然伴隨著一些開銷,所以它只使用,如果沒有其他選擇。

          SDP

          會話描述協議 (SDP)是描述連接的多媒體內容的標準,如分辨率、格式、編解碼器、加密等,以便在數據傳輸時兩個對等可以相互理解。這在本質上是描述內容而不是媒體內容本身的元數據。

          因此,從技術上講,SDP 并不是真正的協議,而是用于描述設備之間共享介質連接的數據格式。

          記錄 SDP 遠遠超出了此文檔的范圍;然而,這里有一些值得注意的事情。

          webRTC API

          WebRTC主要讓瀏覽器具備三個作用。

          • 獲取音頻和視頻
          • 進行音頻和視頻通信
          • 進行任意數據的通信

          WebRTC共分成三個API,分別對應上面三個作用。

          • MediaStream (又稱getUserMedia)
          • RTCPeerConnection
          • RTCDataChannel

          相關學習資料推薦,點擊下方鏈接免費報名,先碼住不迷路~】

          音視頻免費學習地址:FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級開發

          【免費分享】音視頻學習資料包、大廠面試題、技術視頻和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點擊788280672加群免費領取~

          getUserMedia

          概述

          navigator.getUserMedia方法目前主要用于,在瀏覽器中獲取音頻(通過麥克風)和視頻(通過攝像頭),將來可以用于獲取任意數據流,比如光盤和傳感器。

          下面的代碼用于檢查瀏覽器是否支持getUserMedia方法。

          navigator.getUserMedia=navigator.getUserMedia ||
                                    navigator.webkitGetUserMedia ||
                                    navigator.mozGetUserMedia ||
                                    navigator.msGetUserMedia;
          
          if (navigator.getUserMedia) {
              // 支持
          } else {
              // 不支持
          }

          Chrome 21, Opera 18和Firefox 17,支持該方法。目前,IE還不支持,上面代碼中的msGetUserMedia,只是為了確保將來的兼容。

          getUserMedia方法接受三個參數。

          navigator.getUserMedia({
              video: true, 
              audio: true
          }, onSuccess, onError);
          

          getUserMedia的第一個參數是一個對象,表示要獲取哪些多媒體設備,上面的代碼表示獲取攝像頭和麥克風;onSuccess是一個回調函數,在獲取多媒體設備成功時調用;onError也是一個回調函數,在取多媒體設備失敗時調用。

          下面是一個例子。

          var constraints={video: true};
          
          function onSuccess(stream) {
            var video=document.querySelector("video");
            video.src=window.URL.createObjectURL(stream);
          }
          
          function onError(error) {
            console.log("navigator.getUserMedia error: ", error);
          }
          
          navigator.getUserMedia(constraints, onSuccess, onError);

          如果網頁使用了getUserMedia方法,瀏覽器就會詢問用戶,是否同意瀏覽器調用麥克風或攝像頭。如果用戶同意,就調用回調函數onSuccess;如果用戶拒絕,就調用回調函數onError。

          onSuccess回調函數的參數是一個數據流對象stream。stream.getAudioTracks方法和stream.getVideoTracks方法,分別返回一個數組,其成員是數據流包含的音軌和視軌(track)。使用的聲音源和攝影頭的數量,決定音軌和視軌的數量。比如,如果只使用一個攝像頭獲取視頻,且不獲取音頻,那么視軌的數量為1,音軌的數量為0。每個音軌和視軌,有一個kind屬性,表示種類(video或者audio),和一個label屬性(比如FaceTime HD Camera (Built-in))。

          onError回調函數接受一個Error對象作為參數。Error對象的code屬性有如下取值,說明錯誤的類型。

          • PERMISSION_DENIED:用戶拒絕提供信息。
          • NOT_SUPPORTED_ERROR:瀏覽器不支持硬件設備。
          • MANDATORY_UNSATISFIED_ERROR:無法發現指定的硬件設備。

          范例:獲取攝像頭

          下面通過getUserMedia方法,將攝像頭拍攝的圖像展示在網頁上。

          首先,需要先在網頁上放置一個video元素。圖像就展示在這個元素中。

          <video id="webcam"></video>

          然后,用代碼獲取這個元素。

          function onSuccess(stream) {
              var video=document.getElementById('webcam');
          }

          接著,將這個元素的src屬性綁定數據流,攝影頭拍攝的圖像就可以顯示了。

          function onSuccess(stream) {
              var video=document.getElementById('webcam');
              if (window.URL) {
          	    video.src=window.URL.createObjectURL(stream);
          	} else {
          		video.src=stream;
          	}
          
          	video.autoplay=true; 
          	// 或者 video.play();
          }
          
          if (navigator.getUserMedia) {
          	navigator.getUserMedia({video:true}, onSuccess);
          } else {
          	document.getElementById('webcam').src='somevideo.mp4';
          }

          在Chrome和Opera中,URL.createObjectURL方法將媒體數據流(MediaStream)轉為一個二進制對象的URL(Blob URL),該URL可以作為video元素的src屬性的值。 在Firefox中,媒體數據流可以直接作為src屬性的值。Chrome和Opera還允許getUserMedia獲取的音頻數據,直接作為audio或者video元素的值,也就是說如果還獲取了音頻,上面代碼播放出來的視頻是有聲音的。

          獲取攝像頭的主要用途之一,是讓用戶使用攝影頭為自己拍照。Canvas API有一個ctx.drawImage(video, 0, 0)方法,可以將視頻的一個幀轉為canvas元素。這使得截屏變得非常容易。

          <video autoplay></video>
          <img src="">
          <canvas style="display:none;"></canvas>
          
          <script>
            var video=document.querySelector('video');
            var canvas=document.querySelector('canvas');
            var ctx=canvas.getContext('2d');
            var localMediaStream=null;
          
            function snapshot() {
              if (localMediaStream) {
                ctx.drawImage(video, 0, 0);
                // “image/webp”對Chrome有效,
                // 其他瀏覽器自動降為image/png
                document.querySelector('img').src=canvas.toDataURL('image/webp');
              }
            }
          
            video.addEventListener('click', snapshot, false);
          
            navigator.getUserMedia({video: true}, function(stream) {
              video.src=window.URL.createObjectURL(stream);
              localMediaStream=stream;
            }, errorCallback);
          </script>

          范例:捕獲麥克風聲音

          通過瀏覽器捕獲聲音,需要借助Web Audio API。

          window.AudioContext=window.AudioContext ||
                                window.webkitAudioContext;
          
          var context=new AudioContext();
          
          function onSuccess(stream) {
          	var audioInput=context.createMediaStreamSource(stream);
          	audioInput.connect(context.destination);
          }
          
          navigator.getUserMedia({audio:true}, onSuccess);

          捕獲的限定條件

          getUserMedia方法的第一個參數,除了指定捕獲對象之外,還可以指定一些限制條件,比如限定只能錄制高清(或者VGA標準)的視頻。

          var hdConstraints={
            video: {
              mandatory: {
                minWidth: 1280,
                minHeight: 720
              }
            }
          };
          
          navigator.getUserMedia(hdConstraints, onSuccess, onError);
          
          var vgaConstraints={
            video: {
              mandatory: {
                maxWidth: 640,
                maxHeight: 360
              }
            }
          };
          
          navigator.getUserMedia(vgaConstraints, onSuccess, onError);

          MediaStreamTrack.getSources()

          如果本機有多個攝像頭/麥克風,這時就需要使用MediaStreamTrack.getSources方法指定,到底使用哪一個攝像頭/麥克風。

          MediaStreamTrack.getSources(function(sourceInfos) {
            var audioSource=null;
            var videoSource=null;
          
            for (var i=0; i !=sourceInfos.length; ++i) {
              var sourceInfo=sourceInfos[i];
              if (sourceInfo.kind==='audio') {
                console.log(sourceInfo.id, sourceInfo.label || 'microphone');
          
                audioSource=sourceInfo.id;
              } else if (sourceInfo.kind==='video') {
                console.log(sourceInfo.id, sourceInfo.label || 'camera');
          
                videoSource=sourceInfo.id;
              } else {
                console.log('Some other kind of source: ', sourceInfo);
              }
            }
          
            sourceSelected(audioSource, videoSource);
          });
          
          function sourceSelected(audioSource, videoSource) {
            var constraints={
              audio: {
                optional: [{sourceId: audioSource}]
              },
              video: {
                optional: [{sourceId: videoSource}]
              }
            };
          
            navigator.getUserMedia(constraints, onSuccess, onError);
          }

          上面代碼表示,MediaStreamTrack.getSources方法的回調函數,可以得到一個本機的攝像頭和麥克風的列表,然后指定使用最后一個攝像頭和麥克風。

          RTCPeerConnectionl,RTCDataChannel

          RTCPeerConnectionl

          RTCPeerConnection的作用是在瀏覽器之間建立數據的“點對點”(peer to peer)通信,也就是將瀏覽器獲取的麥克風或攝像頭數據,傳播給另一個瀏覽器。這里面包含了很多復雜的工作,比如信號處理、多媒體編碼/解碼、點對點通信、數據安全、帶寬管理等等。

          不同客戶端之間的音頻/視頻傳遞,是不用通過服務器的。但是,兩個客戶端之間建立聯系,需要通過服務器。服務器主要轉遞兩種數據。

          • 通信內容的元數據:打開/關閉對話(session)的命令、媒體文件的元數據(編碼格式、媒體類型和帶寬)等。
          • 網絡通信的元數據:IP地址、NAT網絡地址翻譯和防火墻等。

          WebRTC協議沒有規定與服務器的通信方式,因此可以采用各種方式,比如WebSocket。通過服務器,兩個客戶端按照Session Description Protocol(SDP協議)交換雙方的元數據。

          下面是一個示例。

          var signalingChannel=createSignalingChannel();
          var pc;
          var configuration=...;
          
          // run start(true) to initiate a call
          function start(isCaller) {
              pc=new RTCPeerConnection(configuration);
          
              // send any ice candidates to the other peer
              pc.onicecandidate=function (evt) {
                  signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
              };
          
              // once remote stream arrives, show it in the remote video element
              pc.onaddstream=function (evt) {
                  remoteView.src=URL.createObjectURL(evt.stream);
              };
          
              // get the local stream, show it in the local video element and send it
              navigator.getUserMedia({ "audio": true, "video": true }, function (stream) {
                  selfView.src=URL.createObjectURL(stream);
                  pc.addStream(stream);
          
                  if (isCaller)
                      pc.createOffer(gotDescription);
                  else
                      pc.createAnswer(pc.remoteDescription, gotDescription);
          
                  function gotDescription(desc) {
                      pc.setLocalDescription(desc);
                      signalingChannel.send(JSON.stringify({ "sdp": desc }));
                  }
              });
          }
          
          signalingChannel.onmessage=function (evt) {
              if (!pc)
                  start(false);
          
              var signal=JSON.parse(evt.data);
              if (signal.sdp)
                  pc.setRemoteDescription(new RTCSessionDescription(signal.sdp));
              else
                  pc.addIceCandidate(new RTCIceCandidate(signal.candidate));
          };

          RTCPeerConnection帶有瀏覽器前綴,Chrome瀏覽器中為webkitRTCPeerConnection,Firefox瀏覽器中為

          mozRTCPeerConnection。Google維護一個函數庫adapter.js,用來抽象掉瀏覽器之間的差異。

          RTCDataChannel

          RTCDataChannel的作用是在點對點之間,傳播任意數據。它的API與WebSockets的API相同。

          下面是一個示例。


          var pc=new webkitRTCPeerConnection(servers,
            {optional: [{RtpDataChannels: true}]});
          
          pc.ondatachannel=function(event) {
            receiveChannel=event.channel;
            receiveChannel.onmessage=function(event){
              document.querySelector("div#receive").innerHTML=event.data;
            };
          };
          
          sendChannel=pc.createDataChannel("sendDataChannel", {reliable: false});
          
          document.querySelector("button#send").onclick=function (){
            var data=document.querySelector("textarea#send").value;
            sendChannel.send(data);
          };

          Chrome 25、Opera 18和Firefox 22支持RTCDataChannel。

          外部函數庫

          由于這兩個API比較復雜,一般采用外部函數庫進行操作。目前,視頻聊天的函數庫有SimpleWebRTC、easyRTC、webRTC.io,點對點通信的函數庫有PeerJS、Sharefest。

          下面是SimpleWebRTC的示例。

          var webrtc=new WebRTC({
            localVideoEl: 'localVideo',
            remoteVideosEl: 'remoteVideos',
            autoRequestMedia: true
          });
          
          webrtc.on('readyToCall', function () {
              webrtc.joinRoom('My room name');
          });

          下面是PeerJS的示例。

          var peer=new Peer('someid', {key: 'apikey'});
          peer.on('connection', function(conn) {
            conn.on('data', function(data){
              // Will print 'hi!'
              console.log(data);
            });
          });
          
          // Connecting peer
          var peer=new Peer('anotherid', {key: 'apikey'});
          var conn=peer.connect('someid');
          conn.on('open', function(){
            conn.send('hi!');
          });

          原文 WebRTC實現瀏覽器上的音視頻通信 - 掘金


          主站蜘蛛池模板: 日韩精品无码免费一区二区三区| 精品一区高潮喷吹在线播放| 寂寞一区在线观看| 韩国福利一区二区美女视频| 亚洲第一区精品日韩在线播放| 亚洲综合一区国产精品| 日本高清成本人视频一区| 精品国产日韩一区三区| 精品国产一区二区三区香蕉事 | 台湾无码AV一区二区三区| bt7086福利一区国产| 国精品无码一区二区三区在线蜜臀| 内射女校花一区二区三区| 波多野结衣高清一区二区三区| 国产精品一区二区在线观看| 精品久久国产一区二区三区香蕉| 亚洲日韩国产一区二区三区在线| 国产午夜精品一区理论片| 日本激情一区二区三区| 日韩一区二区三区视频| 久久高清一区二区三区| 国语对白一区二区三区| 中文字幕无码不卡一区二区三区 | 另类国产精品一区二区| 日产亚洲一区二区三区| 精品一区二区三区水蜜桃| 国产一区二区三区不卡观| 婷婷亚洲综合一区二区| 亚洲一区二区三区写真| 中文日韩字幕一区在线观看| 成人一区二区三区视频在线观看 | 无码视频免费一区二三区| 久久精品国产一区二区三区不卡| 北岛玲在线一区二区| 夜夜精品视频一区二区| 亚洲电影一区二区三区| 91福利国产在线观看一区二区 | 久久99国产一区二区三区| 中文字幕人妻第一区| 国产精品日本一区二区不卡视频 | 国产一区二区免费|