في Web API، هناك كائنات وخصائص ووظائف مفيدة جدًا يمكن استخدامها لأداء مهام صغيرة مثل الوصول إلى DOM، إلى مهام معقدة مثل معالجة الصوت والفيديو. تتضمن واجهات برمجة التطبيقات الشائعة Canvas وWeb Worker وHistory وFetch وما إلى ذلك. دعونا نلقي نظرة على بعض واجهات برمجة تطبيقات الويب غير الشائعة ولكنها مفيدة!
نظرة عامة على النص الكامل:
Web Audio API
ملء الشاشة API
Web Speech API
Web Bluetooth API
Vibration API
Broadcast Channel
Clipboard API
Web Share API
Audio API تسمح لنا بتشغيل تدفقات الصوت على الويب، ويمكن استخدامها لإضافة الصوت مصادر على تأثيرات الويب والمرشحات. يمكن أن يأتي مصدر الصوت من <audio>
، أو ملف مصدر فيديو/صوت، أو دفق شبكة صوتية.
لننظر إلى مثال:
<body> <الرأس> <h2>واجهات برمجة تطبيقات الويب<h2> </header> <div class="web-api-cnt"> <div class="web-api-card"> <div class="web-api-card-head"> التجريبي الصوت </div> <div class="web-api-card-body"> <div id="error" class=" Close"></div> <ديف> <عناصر التحكم في الصوت src="./audio.mp3" id="audio"></audio> </div> <ديف> <button onclick="audioFromAudioFile.init()">Init</button> <button onclick="audioFromAudioFile.play()">تشغيل</button> <button onclick="audioFromAudioFile.pause()">إيقاف مؤقت</button> <button onclick="audioFromAudioFile.stop()">إيقاف</button> </div> <ديف> <span>المجلد: <input onchange = "audioFromAudioFile.changeVolume()" type = "range" id = "vol" min = "1" max = "2" step = "0.01" value = "1" /></ فترة> <span>التحريك: <input onchange="audioFromAudioFile.changePan()" type="range" id="panner" min="-1" max="1" step="0.01" value="0" />< /فترة> </div> </div> </div> </div> </الجسم> <النص البرمجي> const l = console.log دع audioFromAudioFile = (function() { فار الصوتContext varvolNode varpannerNode فار وسائل الإعلام المصدر وظيفة الحرف الأول () { ل ("الحرف الأول") يحاول { audioContext = AudioContext () جديد mediaSource = audioContext.createMediaElementSource(audio) volNode = audioContext.createGain() volNode.gain.value = 1 pannerNode = new StereoPannerNode(audioContext, { pan:0 }) mediaSource.connect(volNode).connect(pannerNode).connect(audioContext.destination) } قبض (ه) { error.innerHTML = "هذا الجهاز لا يدعم Web Audio API" error.classList.remove("إغلاق") } } تشغيل الوظيفة () { تشغيل الصوت () } توقف الوظيفة () { إيقاف الصوت () } توقف الوظيفة () { توقف الصوت () } تغيير حجم الدالة () { volNode.gain.value = this.value ل ("نطاق المجلد:"، this.value) } وظيفة تغيير بان () { pannerNode.gain.value = this.value ل ("نطاق عموم:"، this.value) } يعود { حرف أولي, يلعب، يوقف، قف، تغيير, ChangeVolume } })() </script>
ينقل هذا المثال الصوت من عنصر <audio>
إلى AudioContext
. وتتم إضافة المؤثرات الصوتية (مثل التحريك) إلى مصدر الصوت قبل إخراجها إلى مخرج الصوت (مكبر الصوت).
يقوم ButtonInit باستدعاء الدالة init
عند النقر عليها. سيؤدي هذا إلى إنشاء مثيل AudioContext
وتعيينه كـ audioContext
. بعد ذلك، يقوم بإنشاء مصدر وسائط createMediaElementSource(audio)
، ويمرر عنصر الصوت كمصدر الصوت. يتم إنشاء عقدة مستوى الصوت volNode
بواسطة createGain
ويمكن استخدامها لضبط مستوى الصوت. استخدم بعد ذلك StereoPannerNode
لإعداد تأثير التحريك، وأخيرًا قم بتوصيل العقدة بمصدر الوسائط.
انقر فوق الأزرار (تشغيل، إيقاف مؤقت، إيقاف) لتشغيل الصوت وإيقافه مؤقتًا وإيقافه. تحتوي الصفحة على شريط تمرير لنطاق الصوت والتحريك، ويمكنك ضبط مستوى الصوت وتأثير التحريك عن طريق تحريك شريط التمرير.
الموارد ذات الصلة:
تُستخدم واجهة برمجة تطبيقات ملء الشاشة لتمكين وضع ملء الشاشة في الويب التطبيقات، والتي تتيح لك عرض الصفحة/العنصر في وضع ملء الشاشة. على هواتف Android، فإنه يتجاوز نافذة المتصفح وشريط الحالة في الجزء العلوي من Android (حيث يتم عرض حالة الشبكة وحالة البطارية وما إلى ذلك).
طريقة API بملء الشاشة:
requestFullscreen
: عرض العنصر المحدد في وضع ملء الشاشة على النظام، وإغلاق التطبيقات الأخرى بالإضافة إلى عناصر المتصفح وواجهة مستخدم النظام.exitFullscreen
: الخروج من وضع ملء الشاشة والانتقال إلى الوضع العادي.دعونا نلقي نظرة على مثال شائع لاستخدام وضع ملء الشاشة لمشاهدة مقطع فيديو:
<body> <الرأس> <h2>واجهات برمجة تطبيقات الويب<h2> </header> <div class="web-api-cnt"> <div class="web-api-card"> <div class="web-api-card-head"> العرض التجريبي بملء الشاشة </div> <div class="web-api-card-body"> <div id="error" class=" Close"></div> <ديف> تجعل واجهة برمجة التطبيقات هذه وضع ملء الشاشة لصفحة الويب الخاصة بنا أمرًا ممكنًا، فهي تتيح لك تحديد العنصر الذي تريد عرضه في وضع ملء الشاشة، ثم تقوم بإيقاف تشغيل ميزات نافذة المتصفحات مثل شريط URL وجزء النافذة وتقديم العنصر ليأخذ كامل الشاشة. العرض والارتفاع للنظام. في هواتف Android، سيتم إزالة نافذة المتصفحات وواجهة مستخدم Android حيث يتم عرض حالة الشبكة وحالة البطارية وعرض العنصر بالعرض الكامل لنظام Android. </div> <div class="video-stage"> <video id="video" src="./video.mp4"></video> <button onclick="toggle()">تفعيل وضع ملء الشاشة</button> </div> <ديف> تجعل واجهة برمجة التطبيقات هذه وضع ملء الشاشة لصفحة الويب الخاصة بنا أمرًا ممكنًا، فهي تتيح لك تحديد العنصر الذي تريد عرضه في وضع ملء الشاشة، ثم تقوم بإيقاف تشغيل ميزات نافذة المتصفحات مثل شريط URL وجزء النافذة وتقديم العنصر ليأخذ كامل الشاشة. العرض والارتفاع للنظام. في هواتف Android، سيتم إزالة نافذة المتصفحات وواجهة مستخدم Android حيث يتم عرض حالة الشبكة وحالة البطارية وعرض العنصر بالعرض الكامل لنظام Android. </div> </div> </div> </div> </الجسم> <النص البرمجي> const l =console.log تبديل الوظيفة () { const videoStageEl = document.querySelector(".video-stage") إذا (videoStageEl.requestFullscreen) { إذا (!document.fullscreenElement){ videoStageEl.requestFullscreen() } آخر { document.exitFullscreen() } } آخر { error.innerHTML = "هذا الجهاز لا يدعم واجهة برمجة تطبيقات ملء الشاشة" error.classList.remove("إغلاق") } } </script>
كما ترون، عنصر الفيديو موجود في عنصر div#video-stage، مع زر تبديل ملء الشاشة.
نريد أن يعرض العنصر div#video-stage
ملء الشاشة عند النقر فوق الزر للتبديل إلى وضع ملء الشاشة. تنفيذ وظيفة toggle
كما يلي:
function toggle() { const videoStageEl = document.querySelector(".video-stage") إذا (!document.fullscreenElement) videoStageEl.requestFullscreen() آخر document.exitFullscreen() }
هنا، يتم استخدام querySelector
للعثور على عنصر div#video-stage
وحفظ مثيل HTMLDivElement الخاص به على videoStageEl
.
بعد ذلك، استخدم الخاصية document.fullsreenElement
لتحديد ما إذا كان document
ملء الشاشة، لذلك يمكن استدعاء requestFullscreen()
على videoStageEl
. وهذا سيجعل div#video-stage
يشغل عرض الجهاز بالكامل.
إذا قمت بالنقر فوق الزر Toggle Fullscreen في وضع ملء الشاشة، فسيتم استدعاء exitFullcreen
في document
، بحيث يعود عرض واجهة المستخدم إلى العرض العادي (الخروج من ملء الشاشة).
الموارد ذات الصلة:
توفر واجهة برمجة تطبيقات الكلام على الويب تركيب الكلام والتعرف على الكلام تمت إضافة وظائف إلى تطبيقات الويب. باستخدام واجهة برمجة التطبيقات هذه، سنكون قادرين على إصدار أوامر صوتية لتطبيقات الويب، تمامًا كما هو الحال على Android من خلال Google Speech أو باستخدام Cortana في Windows.
دعونا نلقي نظرة على مثال بسيط باستخدام Web Speech API لتنفيذ تحويل النص إلى كلام وتحويل الكلام إلى نص:
<body> <الرأس> <h2>واجهات برمجة تطبيقات الويب<h2> </header> <div class="web-api-cnt"> <div id="error" class=" Close"></div> <div class="web-api-card"> <div class="web-api-card-head"> العرض التوضيحي - تحويل النص إلى كلام </div> <div class="web-api-card-body"> <ديف> <input placeholder = "أدخل النص هنا" type = "text" id = "textToSpeech" /> </div> <ديف> <button onclick="speak()">اضغط للتحدث</button> </div> </div> </div> <div class="web-api-card"> <div class="web-api-card-head"> العرض التوضيحي - تحويل الكلام إلى نص </div> <div class="web-api-card-body"> <ديف> <textarea placeholder="سيظهر النص هنا عند بدء التحدث." id="speechToText"></textarea> </div> <ديف> <button onclick="tapToSpeak()">انقر وتحدث إلى الميكروفون</button> </div> </div> </div> </div> </الجسم> <النص البرمجي> يحاول { فار الكلام = جديد SpeechSynthesisUtterance () var SpeechRecognition = SpeechRecognition; التعرف على فار = التعرف على الكلام الجديد () } قبض (ه) { error.innerHTML = "هذا الجهاز لا يدعم Web Speech API" error.classList.remove("إغلاق") } وظيفة التحدث () { الكلام.نص = textToSpeech.value حجم الكلام = 1 معدل الكلام=1 الكلام. الملعب=1 window.speechSynthesis.speak (الكلام) } وظيفة تاب تو سبيك () { الاعتراف.onstart = وظيفة () { } الاعتراف.onresult = وظيفة (الحدث) { const curr = events.resultIndex نسخة ثابتة = حدث.نتائج[curr][0].transcript خطاب ToText.value = نسخة } الاعتراف.onerror = وظيفة (إيف) { console.error(إيف) } التعرف على البداية () } </script>
العرض التوضيحي الأول - تحويل النص إلى كلام يوضح استخدام واجهة برمجة التطبيقات هذه مع حقل إدخال بسيط يتلقى نص الإدخال وزرًا لتنفيذ عمليات الكلام.
وظيفة التحدث () { خطاب ثابت = SpeechSynthesisUtterance () جديد الكلام.نص = textToSpeech.value حجم الكلام = 1 معدل الكلام = 1 خطاب. الملعب = 1 window.speechSynthesis.speak (الكلام) }
يقوم بإنشاء مثيل لكائن SpeechSynthesisUtterance()
ويقوم بتعيين النص الذي سيتم نطقه من النص الذي تم إدخاله في مربع الإدخال. بعد ذلك، استخدم كائن speech
لاستدعاء وظيفة SpeechSynthesis#speak
لنطق النص الموجود في مربع الإدخال في مكبر الصوت.
العرض التجريبي الثاني - تحويل الكلام إلى نص يتعرف على الكلام كنص. انقر فوق الزر Tap and Speak into Mic وتحدث في الميكروفون، وسيتم ترجمة ما نقوله إلى المحتوى الموجود في مربع إدخال النص.
سيؤدي النقر فوق الزر Tap and Speak into Mic إلى استدعاء وظيفة TapToSpeak:
function TapToSpeak() { var SpeechRecognition = SpeechRecognition; التعرف الثابت = التعرف على الكلام الجديد () الاعتراف.onstart = وظيفة () { } الاعتراف.onresult = وظيفة (الحدث) { const curr = events.resultIndex نسخة ثابتة = حدث.نتائج[curr][0].transcript خطاب ToText.value = نسخة } الاعتراف.onerror = وظيفة (إيف) { console.error(إيف) } التعرف على البداية () }
هنا يتم إنشاء مثيل SpeechRecognition
ثم يتم تسجيل معالجات الأحداث وعمليات الاسترجاعات. يتم استدعاء onstart
عند بدء التعرف على الكلام، onerror
عند حدوث خطأ. عندما يلتقط التعرف على الكلام خطًا، يتم استدعاء onresult
.
في رد الاتصال onresult
، استخرج المحتويات وضعها في textarea
. لذلك عندما نتحدث في الميكروفون، يظهر النص في محتوى textarea
.
الموارد ذات الصلة:
تتيح لنا Bluetooth API الوصول إلى الأجهزة منخفضة الطاقة على جهاز مزود بتقنية Bluetooth للهواتف المحمولة واستخدامه لمشاركة البيانات من صفحة ويب إلى جهاز آخر.
واجهة برمجة التطبيقات الأساسية هي navigator.bluetooth.requestDevice
. سيؤدي استدعاء هذا إلى قيام المتصفح بمطالبة المستخدم باستخدام محدد الجهاز، حيث يمكن للمستخدم تحديد جهاز أو إلغاء الطلب. يتطلب navigator.bluetooth.requestDevice
كائنًا إلزاميًا. يحدد هذا الكائن عامل التصفية الذي يقوم بإرجاع أجهزة Bluetooth التي تطابق عامل التصفية.
دعونا نلقي نظرة على مثال بسيط باستخدام navigator.bluetooth.requestDevice
API لاسترداد معلومات الجهاز الأساسية من جهاز BLE:
<body> <الرأس> <h2>واجهات برمجة تطبيقات الويب<h2> </header> <div class="web-api-cnt"> <div class="web-api-card"> <div class="web-api-card-head"> تجريبي بلوتوث </div> <div class="web-api-card-body"> <div id="error" class=" Close"></div> <ديف> <div>اسم الجهاز: <span id="dname"></span></div> <div>معرف الجهاز: <span id="did"></span></div> <div>الجهاز المتصل: <span id="dconnected"></span></div> </div> <ديف> <button onclick="bluetoothAction()">احصل على جهاز BLE</button> </div> </div> </div> </div> </الجسم> <النص البرمجي> وظيفة بلوتوث العمل () { إذا (المستكشف.بلوتوث) { navigator.bluetooth.requestDevice({ قبول جميع الأجهزة: صحيح }).ثم (الجهاز => { dname.innerHTML = اسم الجهاز did.innerHTML = Device.id dconnected.innerHTML = Device.connected }).catch(يخطئ => { error.innerHTML = "يا إلهي!! حدث خطأ ما." error.classList.remove("إغلاق") }) } آخر { error.innerHTML = "البلوتوث غير مدعوم." error.classList.remove("إغلاق") } } </script>
سيتم عرض معلومات الجهاز هنا. سيؤدي النقر فوق الزر الحصول على جهاز BLE إلى استدعاء وظيفة bluetoothAction
:
function bluetoothAction(){ navigator.bluetooth.requestDevice({ قبول جميع الأجهزة: صحيح }).ثم (الجهاز => { dname.innerHTML = اسم الجهاز did.innerHTML = Device.id dconnected.innerHTML = Device.connected }).catch(يخطئ => { console.error("يا إلهي!! حدث خطأ ما.") }) }
تقوم وظيفة bluetoothAction
باستدعاء navigator.bluetooth.requestDevice
API مع خيار acceptAllDevices:true
، والذي سيؤدي إلى مسح جميع أجهزة Bluetooth النشطة القريبة وإدراجها. تقوم بإرجاع promise
، لذا قم بحلها للحصول على جهاز معلمة من وظيفة رد الاتصال، وستحتفظ معلمة الجهاز هذه بمعلومات جهاز Bluetooth المدرج. هذا هو المكان الذي نستخدم فيه خصائصه لعرض المعلومات على الجهاز.
الموارد ذات الصلة:
يمكن لواجهة برمجة تطبيقات الاهتزاز أن تجعل أجهزتنا تهتز، كواجهة برمجة تطبيقات الطريقة التي يجب أن نستجيب بها للإخطارات أو التعليقات المادية للبيانات أو المعلومات الجديدة.
طريقة إجراء الاهتزاز هي navigator.vibrate(pattern)
. pattern
هو رقم واحد أو مجموعة من الأرقام التي تصف نمط الاهتزاز.
سيؤدي ذلك إلى توقف الجهاز عن الاهتزاز بعد 200 مللي ثانية:
navigator.vibrate(200) navigator.vibrate([200])
سيؤدي هذا إلى اهتزاز الجهاز لمدة 200 مللي ثانية، وإيقاف مؤقت لمدة 300 مللي ثانية، وأخيرًا اهتزاز لمدة 400 مللي ثانية وتوقف:
يمكن تمرير
navigator.vibrate([200, 300, 400])0,
[]، [ 0،0،0] للقضاء على الاهتزاز.
دعونا نلقي نظرة على مثال بسيط:
<body> <الرأس> <h2>واجهات برمجة تطبيقات الويب<h2> </header> <div class="web-api-cnt"> <div class="web-api-card"> <div class="web-api-card-head"> الاهتزاز التجريبي </div> <div class="web-api-card-body"> <div id="error" class=" Close"></div> <ديف> <input id = "vibTime" type = "number" placeholder = "وقت الاهتزاز" /> </div> <ديف> <button onclick="vibrate()">الاهتزاز</button> </div> </div> </div> </div> </الجسم> <النص البرمجي> إذا (navigator.vibrate) { وظيفة الاهتزاز () { وقت ثابت = vibTime.value إذا (الوقت! = "") navigator.vibrate (الوقت) } } آخر { error.innerHTML = "واجهة برمجة تطبيقات الاهتزاز غير مدعومة في هذا الجهاز." error.classList.remove("إغلاق") } </script>
يوجد مربع إدخال وزر هنا. أدخل مدة الاهتزاز في مربع الإدخال واضغط على الزر. سوف يهتز جهازنا للوقت الذي تم إدخاله.
الموارد ذات الصلة:
تسمح واجهة برمجة تطبيقات قناة البث بتصفح مختلف من نفس المصدر السياق ينقل الرسائل أو البيانات. من بينها، يشير سياق التصفح إلى النوافذ، وعلامات التبويب، وإطارات iframe، والعاملين، وما إلى ذلك.
يتم استخدام فئة BroadcastChannel
لإنشاء قناة أو الانضمام إليها:
const PolicyChannel = new BroadcastChannel("politics")
politics
هي اسم القناة. أي سياق يقوم بتهيئة مُنشئ BroadcastChannel
باستخدام politics
سوف ينضم إلى قناة politics
وسيتلقى أي رسائل يتم إرسالها على القناة ويمكن إرسال الرسائل إلى القناة.
إذا كان هذا هو أول مُنشئ BroadcastChannel
يتعلق politics
، فسيتم إنشاء القناة. يمكنك استخدام BroadcastChannel.postMessage API
لنشر الرسائل إلى القناة. استخدم BroadcastChannel.onmessage
API للاشتراك في رسائل القناة.
دعونا نلقي نظرة على تطبيق دردشة بسيط:
<body> <الرأس> <h2>واجهات برمجة تطبيقات الويب<h2> </header> <div class="web-api-cnt"> <div class="web-api-card"> <div class="web-api-card-head"> قناة البث التجريبي </div> <div class="web-api-card-body"> <div class="page-info">افتح هذه الصفحة في <i>علامة تبويب</i> أو <i>نافذة</i> أو <i>iframe</i> أخرى للدردشة معهم.</div> <div id="error" class=" Close"></div> <div id="displayMsg" style="font-size:19px;text-align:left;"> </div> <div class="chatArea"> <input id="input" type="text" placeholder="اكتب رسالتك" /> <button onclick="sendMsg()">أرسل رسالة إلى القناة</button> </div> </div> </div> </div> </الجسم> <النص البرمجي> const l = console.log; يحاول { var PolicyChannel = new BroadcastChannel("politics") PolicyChannel.onmessage = onMessage فار معرف المستخدم = Date.now() } قبض (ه) { error.innerHTML = "واجهة برمجة تطبيقات BroadcastChannel غير مدعومة في هذا الجهاز." error.classList.remove("إغلاق") } input.addEventListener("keydown"، (e) => { if(e.keyCode === 13 && e.target.value.trim().length > 0) { إرسال رسالة () } }) وظيفة onMessage(e) { const {msg,id}=e.data const newHTML = "<div class='chat-msg'><span><i>"+id+"</i>: "+msg+"</span></div>" DisplayMsg.innerHTML = DisplayMsg.innerHTML + newHTML DisplayMsg.scrollTop = DisplayMsg.scrollHeight } الدالة sendMsg() { PolicyChannel.postMessage({msg:input.value,id:userId}) const newHTML = "<div class='chat-msg'><span><i>أنا</i>: "+input.value+"</span></div>" DisplayMsg.innerHTML = DisplayMsg.innerHTML + newHTML قيمة الإدخال = "" DisplayMsg.scrollTop = DisplayMsg.scrollHeight } </script>
هنا نص وزر بسيط. أدخل رسالتك واضغط على الزر لإرسالها. يقوم ما يلي بتهيئة politicalChannel
وتعيين مستمع حدث onmessage
على politicalChannel
حتى يتمكن من تلقي الرسائل وعرضها.
سيؤدي النقر فوق الزر إلى استدعاء وظيفة sendMsg
. يرسل رسائل إلى القناة politics
عبر BroadcastChannel#postMessage
API. ستتلقى أي علامة تبويب أو إطار iframe أو عامل يقوم بتهيئة هذا البرنامج النصي الرسائل المرسلة من هنا، وبالتالي ستتلقى هذه الصفحة الرسائل المرسلة من سياقات أخرى. الموارد ذات الصلة:
عمليات الحافظة مثل النسخ والقص واللصق هي بعض التطبيقات من الميزات الأكثر شيوعًا في . تمكن Clipboard API مستخدمي الويب من الوصول إلى حافظة النظام وتنفيذ عمليات الحافظة الأساسية.
في السابق، كان من الممكن استخدام document.execCommand
للتفاعل مع حافظة النظام. توفر واجهة برمجة تطبيقات الحافظة غير المتزامنة الحديثة إمكانية الوصول المباشر لقراءة وكتابة محتويات الحافظة.
قراءة المحتوى من الحافظة:
navigator.clipboard.readText().then(clipText => document.getElementById("outbox").innerText = clipText
اكتب المحتوى إلى الحافظة:
function updateClipboard(newClip) {
);
navigator.clipboard.writeText(newClip).then(function() { /* تم ضبط الحافظة بنجاح */ }، وظيفة() { /* فشل الكتابة في الحافظة */ }); }
الموارد ذات الصلة:
Share API يمكن أن تساعدنا في تنفيذ وظائف المشاركة على تطبيقات الويب. إنه يمنح إحساسًا بالمشاركة عبر الهاتف المحمول. فهو يجعل من الممكن مشاركة النصوص والملفات والروابط لتطبيقات أخرى على جهازك.
يمكن الوصول إلى Web Share API من خلال طريقة navigator.share
:
if (navigator.share) { الملاح.مشاركة({ العنوان: "بايدو"، النص: "بايدو"، عنوان URL: '<https://www.baidu.com/>'، }) .then(() => console.log('المشاركة ناجحة')) .catch((خطأ) => console.log('فشلت المشاركة'، خطأ)); }
ينفذ الكود أعلاه مشاركة النص باستخدام JavaScript الأصلي. لاحظ أنه لا يمكننا استدعاء هذه العملية إلا باستخدام حدث onclick
:
function Share({ label, text, title }) { const shareDetails = { title, text }; const HandleSharing = async () => { إذا (navigator.share) { يحاول { في انتظار navigator.share(shareDetails).then(() => console.log("Sent")); } التقاط (خطأ) { console.log(`عفوا! لم أتمكن من المشاركة مع العالم بسبب: ${خطأ}`); } } آخر { // الكود الاحتياطي console.log( "مشاركة الويب غير مدعومة حاليًا على هذا المتصفح. يرجى تقديم رد اتصال" ); } }; يعود ( <زر onClick={handleSharing}> <span>{label</span> </زر> ); }
الموارد ذات الصلة: