ডিআইভি উপাদানকে স্ক্রোল করার সময় কীভাবে পৃষ্ঠা স্ক্রোলিং প্রতিরোধ করবেন?


94

আমি কোনও ডিভের মধ্যে দিয়ে শরীরের স্ক্রোল করার ক্ষমতা প্রতিরোধ করার জন্য বিভিন্ন কার্যকারিতা পর্যালোচনা করেছি এবং পরীক্ষা করেছি এবং এমন একটি ফাংশন সমন্বিত করেছি যা কাজ করা উচিত।

$('.scrollable').mouseenter(function() {
    $('body').bind('mousewheel DOMMouseScroll', function() {
        return false;
    });
    $(this).bind('mousewheel DOMMouseScroll', function() {
        return true;
    });
});
$('.scrollable').mouseleave(function() {
    $('body').bind('mousewheel DOMMouseScroll', function() {
        return true;
    });
});
  • এটি সমস্ত স্ক্রোলিং বন্ধ করছে যেখানে আমি চাইছি যে ধারকটির ভিতরে এখনও স্ক্রোলিং সম্ভব হয় possible
  • এটি মাউস ছুটিতে নিষ্ক্রিয়ও হয় না

কোনও ধারণা, বা এটি করার আরও ভাল উপায়?


তোমার দর্শন লগ করা mousewheel থেকে ফেরত মিথ্যা হিসাবে শরীর সেট, হয়তো এই সমস্যা হয়, আমি অনুমান আপনার ধারক শরীর অধিকার ভিতরে
রিকার্ডো Binns

@ric_bfa হ্যাঁ তবে কীভাবে এটি ঠিক করবেন
RIK

পরিবর্তে বডি, আপনার শ্রেণী / আইডি ধারক সেট করুন
রিকার্ডো বিনস

সম্ভবত আমার স্পষ্ট করা উচিত। যখন মাউসটি '। স্ক্রোলযোগ্য' উপাদানটির ভিতরে থাকবে তখন শরীরের স্ক্রোল করার ক্ষমতাটি নিষ্ক্রিয় করা উচিত
RIK

4
সমস্ত সিএসএস এবং জাভাস্ক্রিপ্টের সাথে এটি করার কোনও উপায় নেই?
ছারভে

উত্তর:


166

আপডেট 2: আমার সমাধানটি ব্রাউজারের নেটিভ স্ক্রোলিং পুরোপুরি অক্ষম করার উপর ভিত্তি করে (যখন কার্সারটি ডিআইভির অভ্যন্তরে থাকে) এবং তারপরে নিজেই জাভাস্ক্রিপ্টের মাধ্যমে ডিআইভি স্ক্রোল করে (এর .scrollTopসম্পত্তি সেট করে )। পৃষ্ঠার স্ক্রোলটি প্রতিরোধ করার জন্য কেবলমাত্র বেছে বেছে ব্রাউজারের স্ক্রোলিংটি অক্ষম করা, তবে ডিআইভি স্ক্রোলটি নয় বরং বিকল্প এবং আইএমওর আরও ভাল পদ্ধতির উপায়। নীচে রডির উত্তরটি দেখুন যা এই সমাধানটি দেখায়।


আপনি এখানে যান:

$( '.scrollable' ).on( 'mousewheel DOMMouseScroll', function ( e ) {
    var e0 = e.originalEvent,
        delta = e0.wheelDelta || -e0.detail;

    this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
    e.preventDefault();
});

লাইভ ডেমো: https://jsbin.com/howojuq/edit?js , আউটপুট

সুতরাং আপনি ম্যানুয়ালি স্ক্রোলের অবস্থান সেট করেছেন এবং তারপরে কেবলমাত্র ডিফল্ট আচরণটি আটকাবেন (যা ডিআইভি বা পুরো ওয়েব পৃষ্ঠাতে স্ক্রোল করা হবে)।

আপডেট 1: ক্রিসটি নীচের মন্তব্যে যেমন jQuery এর নতুন সংস্করণে উল্লিখিত হয়েছে, বদ্বীপ তথ্য .originalEventঅবজেক্টের মধ্যে বাসা বেঁধেছে , অর্থাৎ jQuery এটি আর নিজের কাস্টম ইভেন্ট অবজেক্টে প্রকাশ করে না এবং এর পরিবর্তে আমাদের নেটিভ ইভেন্ট অবজেক্ট থেকে এটি পুনরুদ্ধার করতে হয় ।


4
@ রবিনকাইটনাইট ন্যাপ, এমনটি মনে হচ্ছে না। এখানে কর্মরত ডেমোটি রয়েছে: jsfiddle.net/XNwbt/1 এবং এখানে সেই লাইনগুলি সরিয়ে ডেমো দেওয়া হয়েছে: jsfiddle.net/XNwbt/2
Vidas

4
আপনার ম্যানুয়াল স্ক্রোলিং ফায়ারফক্স 10 এ পিছনে রয়েছে, কমপক্ষে লিনাক্স এবং ম্যাকের দিকে। আপনি যদি এটি তৈরি করেন তবে সঠিকভাবে কাজ করছেন বলে মনে হচ্ছে -e.detail, ফায়ারফক্স (ম্যাক, লিনাক্স), সাফারি (ম্যাক) এবং ক্রোমিয়াম (লিনাক্স) এ পরীক্ষিত।
আনোমি

4
@ অ্যানমি এটি সঠিক। মজিলার .detailচিহ্নটি .wheelData(যা ক্রোম / আইই এর আছে) সাইন এর সাথে মিলে না , তাই আমাদের এটি ম্যানুয়ালি উল্টাতে হবে। আমার উত্তর ঠিক করার জন্য ধন্যবাদ।
Vidime বিদাস

8
আমি এটি ব্যবহার করেছি, ধন্যবাদ! আমার এটি যোগ করার দরকার ছিল:if( e.originalEvent ) e = e.originalEvent;
নিকসো

4
@ আইমেভিডাস আমি আমার সফ্টওয়্যারটিতে এটি প্রয়োগ করার পরে আমি এটিতে একটি সামঞ্জস্য করেছি। তাত্পর্যপূর্ণ নয় তবে সম্ভবত যখন উপাদানটির কোনও স্ক্রোল নেই তখন অচলাবস্থায় স্ক্রোলিং রোধ করতে স্ক্রোল সম্পত্তিটির জন্য স্যানিটি চেক যুক্ত করুন। if ( $(this)[0].scrollHeight !== $(this).outerHeight() ) { //yourcode }কেবল তখনই কার্যকর করা হবে যখন কোনও স্ক্রোলবার থাকবে।
ব্যবহারকারী0000001

30

আপনি যদি পুরনো আইই সংস্করণগুলির সাথে সামঞ্জস্যতা (। 8) এর বিষয়ে চিন্তা না করেন তবে আপনি একটি কাস্টম jQuery প্লাগইন তৈরি করতে পারেন এবং তারপরে এটি উপচে পড়া উপাদানটিতে কল করতে পারেন।

এই সমাধানটির প্রস্তাবিত এক আইমেসের চেয়েও বেশি সুবিধা রয়েছে, কারণ এটি স্ক্রোলিং আচরণটি ওভাররাইট করে না - উপযুক্ত হলে এটি কেবল এটিকে অবরুদ্ধ করে।

$.fn.isolatedScroll = function() {
    this.bind('mousewheel DOMMouseScroll', function (e) {
        var delta = e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail,
            bottomOverflow = this.scrollTop + $(this).outerHeight() - this.scrollHeight >= 0,
            topOverflow = this.scrollTop <= 0;

        if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) {
            e.preventDefault();
        }
    });
    return this;
};

$('.scrollable').isolatedScroll();

4
ধন্যবাদ! আমি ডিফল্ট আচরণ ওভাররাইট না করা আরও উপযুক্ত বলে মনে করি। ক্রস ব্রাউজার সমর্থন করতে এটি jQuery মাউস হুইল প্লাগইন ব্যবহার করা যেতে পারে ।
মেটিয়া

দুর্ভাগ্যক্রমে এটি ক্রোম 52 (ওএসএক্স 10.10) এ চটকদার মনে হয়। যদিও সাফারিতে পুরোপুরি কাজ করে।
তুষারপাত

4
ধন্যবাদ! অন্যান্য সমাধানগুলি স্ক্রোলিংটিকে অতি ধীর এবং বগি তৈরি করেছে
Agrublev

@Wjcikstefan, আমি ক্রোমে এই সতর্কতাটি পেয়ে যাচ্ছি:[Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
সৈয়দ

21

আমি মনে করি কখনও কখনও মাউসস্ক্রোল ইভেন্টটি বাতিল করা সম্ভব: http://jsfiddle.net/rudiedirkx/F8qSq/show/

$elem.on('wheel', function(e) {
    var d = e.originalEvent.deltaY,
        dir = d < 0 ? 'up' : 'down',
        stop = (dir == 'up' && this.scrollTop == 0) || 
               (dir == 'down' && this.scrollTop == this.scrollHeight-this.offsetHeight);
    stop && e.preventDefault();
});

ইভেন্ট হ্যান্ডলারের ভিতরে আপনার জানা দরকার:

  • স্ক্রোলিং দিক
    d = e.originalEvent.deltaY, dir = d < 0 ? 'up' : 'down' কারণ একটি ধনাত্মক সংখ্যা মানে নিচে স্ক্রল করা
  • নীচে
    scrollTopজন্য শীর্ষের জন্য স্ক্রোল অবস্থানscrollHeight - scrollTop - offsetHeight

আপনি যদি

  • স্ক্রোলিং আপ, এবং top = 0, বা
  • স্ক্রোলিং ডাউন, এবং bottom = 0,

ইভেন্টটি বাতিল করুন: e.preventDefault()(এবং এমনকি এমনকি e.stopPropagation())।

আমি মনে করি ব্রাউজারের স্ক্রোলিং আচরণটি ওভাররাইড না করা ভাল। প্রযোজ্য হলে কেবল এটি বাতিল করুন।

এটি প্রোব্ল্ট পুরোপুরি এক্সব্রোজার নয়, তবে এটি খুব কঠিন হতে পারে না। সম্ভবত ম্যাকের দ্বৈত স্ক্রোলের দিকটি যদিও জটিল ...


4
আমি কীভাবে ডিভাইসগুলির জন্য একই কার্যকারিতাটি প্রয়োগ করব (ট্যাবলেট / ফোন) আমার ধারণা
টাচমোভ

12

সিএসএস সম্পত্তি নীচে overscroll-behavior: contain;শিশু উপাদান ব্যবহার করুন


এই স্থানীয় সিএসএস নিয়মের তুলনায় অন্যান্য সমস্ত সমাধান ওভারকিল। সুন্দরভাবে সম্পন্ন.
টেকউইসডম

3

এটি আপনাকে সাহায্য করে কিনা দেখুন:

ডেমো: jsfiddle

$('#notscroll').bind('mousewheel', function() {
     return false
});

সম্পাদনা করুন:

এটা চেষ্টা কর:

    $("body").delegate("div.scrollable","mouseover mouseout", function(e){
       if(e.type === "mouseover"){
           $('body').bind('mousewheel',function(){
               return false;
           });
       }else if(e.type === "mouseout"){
           $('body').bind('mousewheel',function(){
               return true;
           });
       }
    });

আপনার উপাদানগুলি পৃথক, যেখানে আমার একটিতে অন্যটিতে রয়েছে।
RIK

3

একটি কম হ্যাকি সমাধান, আমার মতে আপনি যখন স্ক্রোলযোগ্য ডিভের উপর মাউস রাখবেন তখন শরীরের উপরে লুকানো ওভারফ্লো সেট করা। এটি শরীরকে স্ক্রোলিং থেকে রোধ করবে, তবে একটি অবাঞ্ছিত "জাম্পিং" প্রভাব ঘটবে। নিম্নলিখিত সমাধান যে চারপাশে কাজ করে:

jQuery(".scrollable")
    .mouseenter(function(e) {
        // get body width now
        var body_width = jQuery("body").width();
        // set overflow hidden on body. this will prevent it scrolling
        jQuery("body").css("overflow", "hidden"); 
        // get new body width. no scrollbar now, so it will be bigger
        var new_body_width = jQuery("body").width();
        // set the difference between new width and old width as padding to prevent jumps                                     
        jQuery("body").css("padding-right", (new_body_width - body_width)+"px");
    })
    .mouseleave(function(e) {
        jQuery("body").css({
            overflow: "auto",
            padding-right: "0px"
        });
    })

প্রয়োজনে আপনি নিজের কোডটি আরও স্মার্ট করে তুলতে পারেন। উদাহরণস্বরূপ, আপনি যদি শরীরে ইতিমধ্যে প্যাডিং থাকে এবং আপনি হ্যাঁ, এটিতে নতুন প্যাডিং যুক্ত করে পরীক্ষা করতে পারেন।


3

উপরের সমাধানটিতে ফায়ারফক্স সম্পর্কে কিছুটা ভুল রয়েছে। ফায়ারফক্সে "ডোমমাউসস্ক্রোল" ইভেন্টের কোনও e.detail সম্পত্তি নেই, এই সম্পত্তিটি পেতে আপনার নীচের 'e.originalEvent.detail' লিখতে হবে।

ফায়ারফক্সের জন্য এখানে একটি কার্যক্ষম সমাধান রয়েছে:

$.fn.isolatedScroll = function() {
    this.on('mousewheel DOMMouseScroll', function (e) {
        var delta = e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.originalEvent.detail,
            bottomOverflow = (this.scrollTop + $(this).outerHeight() - this.scrollHeight) >= 0,
            topOverflow = this.scrollTop <= 0;

        if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) {
            e.preventDefault();
        }
    });
    return this;
};

আপনি যখন ডিভের উপরের বা নীচে প্রথম ক্রশটি প্রথম ইভেন্টটি শরীরে নিয়ে যান তখন ব্যতীত এটি বেশ ভাল কাজ করে। ওক্সে ক্রোমে 2-আঙুলের স্পর্শ দিয়ে পরীক্ষা করা।
johnb003

3

এখানে jQuery ছাড়াই একটি সহজ সমাধান যা ব্রাউজারের নেটিভ স্ক্রোলটি ধ্বংস করে না (এটি হ'ল কোনও কৃত্রিম / কুরুচিপূর্ণ স্ক্রোলিং নয়):

var scrollable = document.querySelector('.scrollable');

scrollable.addEventListener('wheel', function(event) {
    var deltaY = event.deltaY;
    var contentHeight = scrollable.scrollHeight;
    var visibleHeight = scrollable.offsetHeight;
    var scrollTop = scrollable.scrollTop;

    if (scrollTop === 0 && deltaY < 0)
        event.preventDefault();
    else if (visibleHeight + scrollTop === contentHeight && deltaY > 0)
        event.preventDefault();
});

লাইভ ডেমো: http://jsfiddle.net/ibcaliax/bwmzfmq7/4/


আমি সবেমাত্র উপরের কোডটি প্রয়োগ করে একটি এনপিএম গ্রন্থাগার প্রকাশ করেছি: npmjs.com/package/doutscrollthebody
Iñaki Baz Castillo

2

অ্যাপ্লিকেশনগুলিতে আমি আমার সমাধানটি ব্যবহার করেছি।

আমি শরীরের ওভারফ্লো অক্ষম করে দিয়ে পুরো ওয়েবসাইট এইচটিএমএলটি ধারক ডিভের ভিতরে রেখেছি। ওয়েবসাইটের পাত্রে ওভারফ্লো হয়েছে এবং তাই ব্যবহারকারী প্রত্যাশা অনুযায়ী পৃষ্ঠাটি স্ক্রোল করতে পারে।

তারপরে আমি একটি উচ্চতর জেড-ইনডেক্স সহ একটি ভাইবোন ডিভ (# প্রিভেন্ট) তৈরি করেছি যা পুরো ওয়েবসাইট জুড়ে। যেহেতু # প্রিভেন্টের উচ্চতর জেড-সূচক রয়েছে তাই এটি ওয়েবসাইটের ধারকটিকে ওভারল্যাপ করে। যখন # প্রিভেন্ট দৃশ্যমান হয় তখন মাউস আর ওয়েবসাইটের ধারকগুলিতে ঘোরাফেরা করে না, সুতরাং স্ক্রোলিং সম্ভব হয় না।

আপনি অবশ্যই অন্য একটি ডিভ রাখতে পারেন, যেমন আপনার মডেল হিসাবে, মার্কআপে # প্রিভেন্টের চেয়ে উচ্চতর জেড-ইনডেক্স রয়েছে। এটি আপনাকে পপ-আপ উইন্ডোগুলি তৈরি করতে দেয় যা স্ক্রোলিং সমস্যায় ভুগছে না।

এই সমাধানটি আরও ভাল কারণ এটি স্ক্রোলবারগুলি আড়াল করে না (জাম্পিং প্রভাবিত করে)। এটি ইভেন্ট শ্রোতার প্রয়োজন হয় না এবং এটি বাস্তবায়ন করা সহজ। এটি সমস্ত ব্রাউজারে কাজ করে, যদিও আই 7 এবং 8 এর সাথে আপনাকে প্রায় খেলতে হবে (আপনার নির্দিষ্ট কোডের উপর নির্ভর করে)।

এইচটিএমএল

<body>
  <div id="YourModal" style="display:none;"></div>
  <div id="Prevent" style="display:none;"></div>
  <div id="WebsiteContainer">
     <div id="Website">
     website goes here...
     </div>
  </div>
</body>

সিএসএস

body { overflow: hidden; }

#YourModal {
 z-index:200;
 /* modal styles here */
}

#Prevent {
 z-index:100;
 position:absolute;
 left:0px;
 height:100%;
 width:100%;
 background:transparent;
}

#WebsiteContainer {
  z-index:50;
  overflow:auto;
  position: absolute;
  height:100%;
  width:100%;
}
#Website {
  position:relative;
}

jquery / js

function PreventScroll(A) { 
  switch (A) {
    case 'on': $('#Prevent').show(); break;
    case 'off': $('#Prevent').hide(); break;
  }
}

স্ক্রোলটি অক্ষম / সক্ষম করুন

PreventScroll('on'); // prevent scrolling
PreventScroll('off'); // allow scrolling

4
আপনার উত্তর সম্পর্কে কিছু তথ্য সহ কোড পোস্ট করার চেয়ে দয়া করে বিবেচনা করুন। আমরা কেবল 'সংশোধন' সরবরাহ করার চেষ্টা করি না, তবে লোকদের শিখতে সহায়তা করি। মূল কোডটিতে কী ভুল ছিল, আপনি কী আলাদাভাবে করেছেন এবং কেন আপনার পরিবর্তন (গুলি) কাজ করেছে তা আপনাকে ব্যাখ্যা করা উচিত।
অ্যান্ড্রু বারবার

1

আমার এই ইভেন্টটি একাধিক উপাদানগুলিতে যুক্ত করা দরকার যার মধ্যে একটি স্ক্রোলবার থাকতে পারে। যে কোনও ক্ষেত্রে কোনও স্ক্রোলবার উপস্থিত ছিল না, মূল স্ক্রোলবারটি যেমনটি করা ঠিক তেমন কাজ করে নি। সুতরাং আমি @ আইম কোডে নীচে একটি ছোট পরিবর্তন করেছি:

$( '.scrollable' ).on( 'mousewheel DOMMouseScroll', function ( e ) {
    if($(this).prop('scrollHeight') > $(this).height())
    {
        var e0 = e.originalEvent, delta = e0.wheelDelta || -e0.detail;

        this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
        e.preventDefault();
    }       
});

এখন, কেবল একটি স্ক্রোলবারযুক্ত উপাদানগুলিই মূল স্ক্রোলটি শুরু হওয়া থামানো থেকে রোধ করবে।


0

বিদাসের উত্তরের বিশুদ্ধ জাভাস্ক্রিপ্ট সংস্করণ el$হ'ল আপনি যে বিমানটি স্ক্রল করছেন তার ডোম নোড।

function onlyScrollElement(event, el$) {
    var delta = event.wheelDelta || -event.detail;
    el$.scrollTop += (delta < 0 ? 1 : -1) * 10;
    event.preventDefault();
}

আপনি এমনকি একাধিকবার সংযুক্ত না তা নিশ্চিত করুন! এখানে একটি উদাহরণ,

var ul$ = document.getElementById('yo-list');
// IE9, Chrome, Safari, Opera
ul$.removeEventListener('mousewheel', onlyScrollElement);
ul$.addEventListener('mousewheel', onlyScrollElement);
// Firefox
ul$.removeEventListener('DOMMouseScroll', onlyScrollElement);
ul$.addEventListener('DOMMouseScroll', onlyScrollElement);

সাবধানতার কথা , সেখানে ফাংশনটি একটি ধ্রুবক হওয়া দরকার, যদি আপনি প্রতিটি বার এটি সংযুক্ত করার আগে পুনরায় ফাংশনটি পুনরায় চালু করেন, অর্থাত্‍। কাজ করবে না।var func = function (...)removeEventListener


0

আপনি জাভাস্ক্রিপ্ট ছাড়াই এটি করতে পারেন। আপনি উভয় ডিভগুলিতে position: fixedএবং স্টাইল সেট করতে পারেন overflow-y: auto। আপনার z-indexসেগুলির একটিটিকে এটির (যদি তারা ওভারল্যাপ করে থাকে) সেট করে অন্যটির চেয়ে উচ্চতর করার প্রয়োজন হতে পারে ।

এখানে CodePen একটি মৌলিক উদাহরণ


0

এখানে একটি প্লাগইন রয়েছে যা নির্দিষ্ট ডিভ স্ক্রোল করার সময় পিতামাতার স্ক্রোল প্রতিরোধের জন্য দরকারী এবং এতে খেলতে বেশ কয়েকটি বিকল্প রয়েছে।

এটি এখানে দেখুন:

https://github.com মোঃ মুহম্মদ ইউনেস / জ্যাকারি- স্ক্রোল লক

ব্যবহার

জাভাস্ক্রিপ্টের মাধ্যমে ট্রিগার স্ক্রোল লক করুন:

$('#target').scrollLock();

মার্কআপের মাধ্যমে ট্রিগার স্ক্রোল লক করুন:

    <!-- HTML -->
<div data-scrollLock
     data-strict='true'
     data-selector='.child'
     data-animation='{"top":"top locked","bottom":"bottom locked"}'
     data-keyboard='{"tabindex":0}'
     data-unblock='.inner'>
     ...
</div>

<!-- JavaScript -->
<script type="text/javascript">
  $('[data-scrollLock]').scrollLock()
</script>

ডেমো দেখুন


0

কেবলমাত্র সম্ভাব্য সমাধান হিসাবে এটির প্রস্তাব দিচ্ছেন যদি আপনি মনে করেন না যে ব্যবহারকারীটির সুস্পষ্ট পরিবর্তনের নেতিবাচক অভিজ্ঞতা থাকবে। যখন মাউস টার্গেট ডিভের উপরে চলে গিয়েছিল তখন আমি কেবল ওভারফ্লোর দেহের ক্লাসটি লুকিয়ে রেখেছিলাম; তারপরে মাউস চলে যাওয়ার পরে আমি দেহের ডিভটি লুকিয়ে থাকা ওভারফ্লোতে বদলে ফেললাম।

ব্যক্তিগতভাবে আমি এটিকে খারাপ দেখাচ্ছে বলে মনে করি না, আমার কোড এটিকে পরিষ্কার করার জন্য টগল ব্যবহার করতে পারে এবং ব্যবহারকারীকে সচেতন না করে এই প্রভাবটি সম্ভব করার পক্ষে সুস্পষ্ট সুবিধা রয়েছে। সুতরাং এটি সম্ভবত হ্যাকিশ-শেষ-রিসর্ট উত্তর।

//listen mouse on and mouse off for the button
pxMenu.addEventListener("mouseover", toggleA1);
pxOptContainer.addEventListener("mouseout", toggleA2);
//show / hide the pixel option menu
function toggleA1(){
  pxOptContainer.style.display = "flex";
  body.style.overflow = "hidden";
}
function toggleA2(){
  pxOptContainer.style.display = "none";
  body.style.overflow = "hidden scroll";
}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.