كتابة مولد معرض صور باستخدام شريط تمرير مضمن



يوم جيد يا اصدقاء!

بدلاً من المقدمة (بيان المشكلة)


بدأ كل شيء بدراسة منزلقات الآخرين (حلول جاهزة على الشبكة ، مثل bxslider و owlcarousel و slick ). في يوم ما ، سأكتب دروسًا تفصيلية حول العمل باستخدام هذه الأدوات (أحلام سعيدة). كانت هناك رغبة في كتابة شريط التمرير. ومع ذلك ، سرعان ما (بما في ذلك بعد قراءة العديد من المقالات حول حبري) ، أدرك أن مجرد منزلق للجبناء. هناك حاجة إلى شيء أكثر راديكالية.

ونتيجة لذلك ، توصلت إلى المهمة التالية: كتابة مولد معرض تكيفي مع شريط تمرير مدمج.

الظروف:

  • القدرة على تحميل أي عدد من الصور (من أي مكان على القرص الصلب الخاص بك).
  • يتكون المعرض من الصور التي تم تحميلها ، ويتم تشكيل الترميز "على الطاير" بما يتوافق مع دلالات HTML5.
  • يبدو المعرض جيدًا على الشاشات ذات الدقة المختلفة.
  • عند النقر فوق أي صورة ، يتم إنشاء شريط تمرير.
  • عند إنشاء شريط تمرير ، تصبح الخلفية معتمة.
  • الصورة التي تم النقر عليها هي الشريحة الأولى.
  • يتم تنفيذ تبديل الشرائح من خلال DOM.
  • يتم تبديل الشرائح بسلاسة.
  • القدرة على التحكم في تبديل الشريحة باستخدام الأزرار ولوحة المفاتيح.
  • القدرة على العودة إلى المعرض بالضغط على الشريحة الحالية والزر وكذلك استخدام لوحة المفاتيح.
  • JavaScript خالص (جميع الترميز عبر JS).
  • رمز الحد الأدنى.

لذا ، دعنا نذهب (كما قال غاغارين ، نذهب إلى الفضاء).

يبدو الترميز كالتالي:
<div class="wrap">
    <input type="file" multiple accept="image/*">
    <button>generate gallery</button>
</div>

من الأشياء المثيرة للاهتمام ، ربما ، سمات متعددة وقبول علامة الإدخال. تسمح لك السمة الأولى بتحميل ملفات متعددة ، والثانية - تعين مرشحًا على أنواع الملفات التي يمكن تنزيلها. في هذه الحالة ، يكون للقبول قيمة "image / *" ، مما يعني أنه يمكن تحميل الصور فقط (أي).

جلب الجمال على الفور (إضافة أنماط):
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    min-height: 100vh;
    background: radial-gradient(circle, skyblue, steelblue);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

button {
    padding: 0.25em;
    font-family: monospace;
    text-transform: uppercase;
    cursor: pointer;
}

.darken {
    position: absolute;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    z-index: -1;
}

.slider {
    width: 100%;
    display: inherit;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
}

figure {
    margin: 0.5em;
    width: 300px;
    display: inherit;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    transition: 0.2s;
}

figcaption {
    font-size: 1.2em;
    text-transform: capitalize;
    text-align: center;
    margin-bottom: 0.25em;
    color: #ddd;
    text-shadow: 1px 1px rgba(0, 0, 0, 0.4);
}

img {
    max-width: 80%;
    max-height: 80vh;
    cursor: pointer;
}

.button {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    background: none;
    border: none;
    outline: none;
    filter: invert();
}

.left {
    left: 2em;
}

.right {
    right: 2em;
}

.close {
    top: 2em;
    right: 1em;
}


لا يوجد شيء للحديث عنه (الظلام - التعتيم).

الانتقال إلى JS.

نجد الزر ونعلق المستمع عليه:
let button = document.querySelector("button");
button.addEventListener("click", generateGallery);

جميع التعليمات البرمجية الإضافية ستكون في وظيفة generGallery لتجنب "غير معرّف" بدون إرجاع:
function generateGallery() {
    //    
}

نجد مدخلات ، نتحقق من أنها ليست فارغة ، نحصل على مجموعة من الملفات التي تم تنزيلها ، حذف .wrap وإنشاء حاوية للمعرض:
let input = document.querySelector("input");
// ,  input  
if(input.files.length == 0) return;
let files = input.files;
//  
let i;

//  .wrap,     
let wrap = document.querySelector(".wrap");
document.body.removeChild(wrap);

//    , ,    gallery
let slider = document.createElement("div");
slider.className = "slider";
document.body.appendChild(slider);

نقوم بفرز مجموعة الملفات ، والحصول على اسم وعنوان كل ملف ، وإنشاء ترميز ، وإنشاء تسميات توضيحية للصور والصور نفسها:
for (i = 0; i < files.length; i++) {
    let file = files[i];
    // URL.createObjectURL         ,         
    // ,   ,       
    //             ,      
    /*let src = URL.createObjectURL(file);*/

    //   
    let name = file.name;

    //   ,      img     
    let src = `img/${name}`;

    //  : figure, figcaption, img
    let figure = document.createElement("figure");
    slider.appendChild(figure);

    let figcaption = document.createElement("figcaption");

    //  ,             ,   
    // (?=\.) -  :     ,    
    //       \w,         
    let regexp = /.+(?=\.)/;
    name = name.match(regexp);
    //   ["", index: 0, input: ".jpg", groups: undefined]
    //    
    figcaption.innerText = name[0];
    figure.appendChild(figcaption);

    //  
    let img = document.createElement("img");
    img.src = src;
    figure.appendChild(img);
}

نريد إنشاء شريط تمرير عند النقر على الصورة. للقيام بذلك ، نجد الشكل بالكامل ونعلقه على كل مستمع:
let figures = document.querySelectorAll("figure");
for (i = 0; i < figures.length; i++) {
    let figure = figures[i];
    figure.addEventListener("click", () => {
        //  ,       figure,   
        generateSlider(figure);
    });
}

بعد ذلك ، نعمل داخل وظيفة generSlider:
function generateSlider(figure) {
    //  
}

تعتيم الخلفية:
darkenBack();
function darkenBack() {
    // ,   
    //  , ,   , 
    if (document.querySelector(".darken") == null) {
        let div = document.createElement("div");
        div.className = "darken";
        document.body.appendChild(div);
    } else {
        let div = document.querySelector(".darken");
        document.body.removeChild(div);
    }
}

سنعرض شريحة واحدة في كل مرة. لا تنس أن مفتاح الشريحة يجب أن يكون سلسًا. من السهل تحقيق ذلك بالشفافية وانتقال صغير. لذلك ، فإننا نركب الصور فوق بعضها البعض ، ونضعها في المنتصف ، ونجعل جميع الصور ، باستثناء الصورة "التي تم النقر عليها" ، شفافة:
for (i = 0; i < figures.length; i++) {
    if (figures[i].hasAttribute("style")) {
        figures[i].removeAttribute("style");
    } else {
        figures[i].setAttribute("style", "margin: 0; width: auto; position: absolute; opacity: 0;");
    }
}

//      / 
if (figure.hasAttribute("style")) {
    figure.style.opacity = 1;
    generateButtons();
} else generateButtons();

بعد ذلك ، قم بإنشاء أزرار لتبديل الشرائح وإغلاق المعرض. تبين أن الرمز طويل وممل (ربما لم يكن إنشاء الأزرار في كل مرة تبدأ فيها شريط التمرير فكرة جيدة):
رمز إنشاء الزر:
function generateButtons() {
    if (document.querySelector(".buttons") == null) {
        //    
        let buttons = document.createElement("div");
        buttons.className = "buttons";
        slider.appendChild(buttons);

        //   
        let leftButton = document.createElement("button");
        leftButton.className = "button left";
        let leftImg = document.createElement("img");
        leftImg.src = "https://thebestcode.ru/media/sliderGenerator/buttons/left.png";
        leftButton.appendChild(leftImg);
        buttons.appendChild(leftButton);
        leftButton.addEventListener("click", () => changeSlide("-"));

        //   
        let rightButton = document.createElement("button");
        rightButton.className = "button right";
        let rightImg = document.createElement("img");
        rightImg.src = "https://thebestcode.ru/media/sliderGenerator/buttons/right.png";
        rightButton.appendChild(rightImg);
        buttons.appendChild(rightButton);
        rightButton.addEventListener("click", () => changeSlide("+"));

        //    
        let closeButton = document.createElement("button");
        closeButton.className = "button close";
        let closeImg = document.createElement("img");
        closeImg.src = "https://thebestcode.ru/media/sliderGenerator/buttons/close.png";
        closeButton.appendChild(closeImg);
        buttons.appendChild(closeButton);
        closeButton.addEventListener("click", () => generateSlider(figure));
    } else {
        //   ,  
        let buttons = document.querySelector(".buttons");
        slider.removeChild(buttons);
    }
}


يتم تنفيذ تبديل الشرائح باستخدام الوظيفة changeSlide ، التي يتم تمريرها كمعامل ، على التوالي ، "+" أو "-":
function changeSlide(e) {
    //    
    for (i = 0; i < figures.length; i++) {
        figures[i].style.opacity = 0;
    }
    if (e == "-") {
        //      ,    
        if (figure == figures[0]) {
            figure = figures[figures.length - 1];
        } else {
            figure = figure.previousElementSibling;
        }
    } else if (e == "+") {
        //      ,    
        if (figure == figures[figures.length - 1]) {
            figure = figures[0];
        } else {
            figure = figure.nextElementSibling;
        }
    }
    //    
    figure.style.opacity = 1;
}

أضف القدرة على تبديل الشرائح وإغلاق المعرض باستخدام لوحة المفاتيح:
document.addEventListener("keydown", e => {
    //  
    if (e.keyCode == 37 || e.keyCode == 189) {
        changeSlide("-");
    //  
    } else if (e.keyCode == 39 || e.keyCode == 187) {
        changeSlide("+");
    // esc
    } else if(e.keyCode == 27) {
        generateSlider(figure);
    }
});

هذا كل شيء ، مولد المعرض التكيفي مع شريط التمرير المدمج جاهز. تمت المهمة. الشروط مستوفاة. نحو النهاية ، أدركت أن "الحد الأدنى للرمز" و "يتم تكوين جميع الترميز على الطاير باستخدام JS" يتعارضان مع بعضهما البعض ، ولكن فات الأوان (هل فات الأوان للاعتذار أم ماذا عن One Republic؟).

يمكن رؤية النتيجة هنا .

لاحظ أنه في Codepen نستخدم URL.createObjectURL للربط بالصور ، لأن Codepen لا يرى مجلد img.

شكرآ لك على أهتمامك.

Source: https://habr.com/ru/post/undefined/


All Articles