css - كيفية تعطيل تحديد اختيار النص؟


15 Answers

في معظم المتصفحات ، يمكن تحقيق ذلك باستخدام أشكال الملكية في خاصية user-select CSS ، التي تم اقتراحها في الأصل ثم تم التخلي عنها في CSS3 والمقترح الآن في CSS UI Level 4 :

*.unselectable {
   -moz-user-select: none;
   -khtml-user-select: none;
   -webkit-user-select: none;

   /*
     Introduced in IE 10.
     See http://ie.microsoft.com/testdrive/HTML5/msUserSelect/
   */
   -ms-user-select: none;
   user-select: none;
}

بالنسبة لـ IE <10 و Opera <15 ، ستحتاج إلى استخدام السمة unselectable للعنصر الذي ترغب في إلغاء تحديده. يمكنك تعيين ذلك باستخدام سمة في HTML:

<div id="foo" unselectable="on" class="unselectable">...</div>

للأسف ، لا يتم توريث هذه الخاصية ، مما يعني أنه يجب عليك وضع سمة في علامة البدء لكل عنصر داخل <div> . إذا كانت هذه مشكلة ، فيمكنك بدلاً من ذلك استخدام جافا سكريبت للقيام بذلك بشكل متكرر لأحفاد عنصر ما:

function makeUnselectable(node) {
    if (node.nodeType == 1) {
        node.setAttribute("unselectable", "on");
    }
    var child = node.firstChild;
    while (child) {
        makeUnselectable(child);
        child = child.nextSibling;
    }
}

makeUnselectable(document.getElementById("foo"));

التحديث بتاريخ 30 نيسان (أبريل) 2014 : يحتاج هذا العبور إلى إعادة التشغيل كلما تمت إضافة عنصر جديد إلى الشجرة ، ولكن يبدو من تعليق بواسطةHan أنه من الممكن تجنب ذلك عن طريق إضافة معالج أحداث mousedown الذي يعين unselectable mousedown الهدف من الحدث. انظر http://jsbin.com/yagekiji/1 للحصول على التفاصيل.

هذا لا يزال لا يغطي جميع الاحتمالات. في حين أنه من المستحيل بدء التحديدات في العناصر غير القابلة للإختيار ، في بعض المتصفحات (IE و Firefox ، على سبيل المثال) لا يزال من المستحيل منع التحديدات التي تبدأ قبل وتنتهي بعد العنصر غير القابل للإلغاء دون جعل المستند بأكمله غير قابل للإلغاء.

Question

بالنسبة للمراسي التي تعمل مثل الأزرار (على سبيل المثال ، الأسئلة والعلامات والمستخدمون وما إلى ذلك في أعلى صفحة ) أو علامات التبويب ، هل توجد طريقة قياسية في CSS لتعطيل تأثير التمييز إذا اختار المستخدم النص عن طريق الخطأ؟

أدرك أنه يمكن إجراء ذلك باستخدام جافا سكريبت ، وأفضى القليل من googling إلى خيار Mozilla-only -moz-user-select .

هل هناك طريقة متوافقة معيارية لتحقيق ذلك باستخدام CSS ، وإذا لم يكن الأمر كذلك ، فما هو منهج "أفضل الممارسات"؟




حتى تصبح خاصية user-select في CSS 3 متاحة ، تدعم المتصفحات -moz-user-select Gecko خاصية -moz-user-select التي وجدتها بالفعل. تدعم مستعرضات WebKit و Blink خاصية -webkit-user-select .

هذا بالطبع غير مدعوم في المتصفحات التي لا تستخدم محرك تقديم جيكو.

لا توجد طريقة سريعة وسهلة متوافقة مع المعايير. استخدام جافا سكريبت هو خيار.

والسؤال الحقيقي هو ، لماذا تريد أن لا يكون المستخدمون قادرين على إبراز بعض العناصر ولصقه ونسخها؟ لم أتعرض لوقت واحد رغبت في عدم السماح للمستخدمين بتمييز جزء معين من موقعي على الويب. العديد من أصدقائي ، بعد أن أمضوا العديد من الساعات في القراءة والكتابة ، سيستخدمون ميزة التمييز كطريقة لتذكر المكان الذي توجد فيه على الصفحة ، أو تقديم علامة بحيث تعرف أعينهم أين يجب أن ينظروا في الخطوة التالية.

المكان الوحيد الذي يمكنني أن أرى فيه هذا الأمر مفيدًا إذا كان لديك أزرار للنماذج التي لا ينبغي نسخها ولصقها إذا قام مستخدم بنسخ موقع الويب ولصقه.




في اختيار الحلول أعلاه ، يتم إيقاف التحديد ، ولكن المستخدم لا يزال يعتقد أنه يمكنك تحديد النص لأن المؤشر لا يزال يتغير. للاحتفاظ بها ثابتة ، سيتعين عليك تعيين مؤشر CSS:

.noselect {
    cursor: default;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
<p>
  Selectable text.
</p>
<p class="noselect">
  Unselectable text.
</p>

سيؤدي هذا إلى جعل النص الخاص بك مستويًا تمامًا ، كما لو كان في تطبيق سطح المكتب.




الحل البديل لـ WebKit :

/* Disable tap highlighting */
-webkit-tap-highlight-color: rgba(0,0,0,0);

لقد وجدتها في مثال CardFlip.




.hidden:after {
    content: attr(data-txt);
}
<p class="hidden" data-txt="Some text you don't want to be selected"></p>

إنها ليست الطريقة الأفضل ، على الرغم من ذلك.




بالنسبة لبرنامج Internet Explorer بالإضافة إلى ذلك ، تحتاج إلى إضافة التركيز على فئة زائفة (.ClassName: focus) ونمط المخطط التفصيلي: لا شيء .

.ClassName,
.ClassName:focus {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    outline-style:none;/*IE*/
}



-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;

*.unselectable {
   -moz-user-select: -moz-none;
   -khtml-user-select: none;
   -webkit-user-select: none;
   user-select: none;
}
<div id="foo" unselectable="on" class="unselectable">...</div>
function makeUnselectable(node) {
    if (node.nodeType == 1) {
        node.unselectable = true;
    }
    var child = node.firstChild;
    while (child) {
        makeUnselectable(child);
        child = child.nextSibling;
    }
}

makeUnselectable(document.getElementById("foo"));
-webkit-user-select:none;
-moz-user-select:none;
onselectstart="return false;"
::selection { background: transparent; }
::-moz-selection { background: transparent; }

* {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: -moz-none;
-o-user-select: none;
user-select: none;
}

p {
-webkit-user-select: text;
-khtml-user-select: text;
-moz-user-select: text;
-o-user-select: text;
user-select: text;
}
<div class="draggable"></div>
.draggable {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}

.draggable input { 
    -webkit-user-select: text; 
    -khtml-user-select: text; 
    -moz-user-select: text; 
    -o-user-select: text; 
    user-select: text; 
 }
if ($.browser.msie) $('.draggable').find(':not(input)').attr('unselectable', 'on');



إذا كنت تستخدم Less و Bootstrap يمكنك كتابة:

.user-select(none);



هذا يعمل في بعض المتصفحات:

::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}

ما عليك سوى إضافة العناصر / معرفات أمام العناصر المحددة بفواصل بدون فراغات ، مثل:

h1::selection,h2::selection,h3::selection,p::selection{ background-color: transparent;}
h1::moz-selection,h2::moz-selection,h3::moz-selection,p::moz-selection{ background-color: transparent;}
h1::webkit-selection,h2::webkit-selection,h3::webkit-selection,p::webkit-selection{ background-color: transparent;}

الاجابات الاخرى افضل. ربما ينبغي النظر إلى هذا كملاذ أخير / catchall.




ملحوظة:

الإجابة الصحيحة صحيحة لأنها تمنعك من تحديد النص. ومع ذلك ، فإنه لا يمنعك من القدرة على نسخ النص ، كما سأعرض مع الصورتين التاليتين (اعتبارًا من 7 نوفمبر 2014).

كما ترى ، لم نتمكن من تحديد الأرقام ، ولكن تمكنا من نسخها.

تم الاختبار على: Ubuntu ، Google Chrome 38.0.2125.111.




سيكون هذا مفيدًا إذا لم يكن اختيار الألوان مطلوبًا أيضًا:

::-moz-selection { background:none; color:none; }
::selection { background:none; color:none; }

... جميع إصلاحات المتصفح الأخرى. ستعمل في Internet Explorer 9 أو أحدث.







تحقق من الحل دون JavaScript:

jsFiddle

li:hover {
    background-color: silver;
}
#id1:before {
    content: "File";
}
#id2:before {
    content: "Edit";
}
#id3:before {
    content: "View";
}
<ul>
    <li><a id="id1" href="www.w1.com"></a>
    <li><a id="id2" href="www.w2.com"></a>
    <li><a id="id3" href="www.w3.com"></a>
</ul>

قائمة منبثقة مع تطبيق http://jsfiddle.net/y4Lac/2/ : http://jsfiddle.net/y4Lac/2/




تحديث سريع للاختراق: آذار 2017 - من CSS-Tricks

إذا وضعت القيمة "لا شيء" لكل سمات تحديد مستخدم CSS كما هو موضح أدناه ، فهناك مشكلة يمكن أن يحدث بها هذا.

.div{
  -webkit-user-select: none; /* Chrome all / Safari all */
  -moz-user-select: none;   /* Firefox all */
  -ms-user-select: none;  /* IE 10+ */
   user-select: none;  /* Likely future */ 
}

كما يقول CSS-Tricks أن المشاكل هي

  • ما زال WebKit يسمح بنسخ النص إذا قمت بتحديد عناصر حوله.

لذا يمكنك أيضًا استخدام الجزء أدناه بدلاً منه لفرض تحديد عنصر بالكامل وهو الحل للمشكلة. كل ما عليك فعله هو تغيير القيمة "لا شيء" إلى "الكل" التي ستبدو هكذا

.force-select {  
  -webkit-user-select: all;  /* Chrome 49+ */
  -moz-user-select: all;     /* Firefox 43+ */
  -ms-user-select: all;      /* No support yet */
  user-select: all;          /* Likely future */   
}



حاول استخدام هذا واحد:

::selection {
    background: transparent;
}

وإذا كنت ترغب في تحديد عدم التحديد داخل عنصر معين ، فقط ضع فئة العنصر أو معرف قبل قاعدة التحديد ، مثل:

.ClassNAME::selection {
    background: transparent;
}
#IdNAME::selection {
    background: transparent;
}





Related