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


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 ، وإذا لم يكن الأمر كذلك ، فما هو منهج "أفضل الممارسات"؟




العمل

CSS:

 -khtml-user-select: none;
 -moz-user-select: none;
 -ms-user-select: none;
  user-select: none;
 -webkit-touch-callout: none;
 -webkit-user-select: none;

يجب أن يعمل هذا ، ولكنه لن يعمل مع المتصفحات القديمة. هناك مشكلة في توافق المستعرض.




 -webkit-user-select: none;  
  -moz-user-select: none;    
  -ms-user-select: none;      
  user-select: none;



في اختيار الحلول أعلاه ، يتم إيقاف التحديد ، ولكن المستخدم لا يزال يعتقد أنه يمكنك تحديد النص لأن المؤشر لا يزال يتغير. للاحتفاظ بها ثابتة ، سيتعين عليك تعيين مؤشر 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>

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




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

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

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

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

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




-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');



على الرغم من أن هذا العنصر الزائف كان في مسودات المستوى 3 من CSS Selectors ، فقد تمت إزالته خلال مرحلة توصية المرشح ، حيث بدا أن سلوكه كان غير محدد ، خاصة مع العناصر المتداخلة ، ولم يتم تحقيق قابلية التشغيل البيني.

تتم مناقشته في كيفية عمل الخيار "اختيار ::" على العناصر المتداخلة .

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

تصميم عادي CSS

p { color: white;  background: black; }

على الاختيار

p::-moz-selection { color: white;  background: black; }
p::selection      { color: white;  background: black; }

سيؤدي عدم السماح للمستخدمين بتحديد النص إلى زيادة مشكلات قابلية الاستخدام.




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

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

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




يرجع تأثير التمييز هذا إلى الإجراء المسمى بـ hover (onMouseHover). عندما تحوم على أي علامة تبويب ، سيتم تغيير اللون. فقط قل على سبيل المثال.

<div class="menu">
 <ul class="effect">
   <li>Questions </li>
   <li>JOBS </li>
   <li>Users</li>
 </ul>
</div>

<!-- CSS CODE -->

.effect:hover{
   color: none;
}

يمكنك إعطاء أي لون إذا كنت ترغب في تمييزه ، وإلا يمكنك إعطاء لا شيء.




يمكنك استخدام CSS أو جافا سكريبت لذلك ، كما يتم دعم طريقة جافا سكريبت في المتصفحات القديمة مثل IE القديمة أيضًا ، ولكن إذا لم تكن هذه هي حالتك ، فاستخدم طريقة CSS بعد ذلك:

HTML / جافا سكريبت:

<body onselectstart='return false;'>
  <h1>This is the Heading!</h1>
  <p>And I'm the text, I won't be selected if you select me.</p>
</body>

HTML / CSS:

.not-selectable {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
<body class="not-selectable">
  <h1>This is the Heading!</h1>
  <p>And I'm the text, I won't be selected if you select me.</p>
</body>




أضف هذا إلى div الأول الذي تريد تعطيل التحديد للنص:

onmousedown='return false;' 
onselectstart='return false;'



للحصول على النتيجة التي أحتاجها ، وجدت أنني مضطر لاستخدام كلا ::selection user-select و user-select

input.no-select:focus { 
    -webkit-touch-callout: none; 
    -webkit-user-select: none; 
    -khtml-user-select: none; 
    -moz-user-select: none; 
    -ms-user-select: none; 
    user-select: none; 
}

input.no-select::selection { 
    background: transparent; 
}

input.no-select::-moz-selection { 
    background: transparent; 
}



بصرف النظر عن خاصية Mozilla-only ، لا ، لا توجد طريقة لتعطيل تحديد النص باستخدام CSS القياسي فقط (حتى الآن).

إذا لاحظت ، لا يقوم بتعطيل اختيار النص لأزرار التنقل الخاصة بهم ، وأوصي بعدم القيام بذلك في معظم الحالات ، نظرًا لأنه يعدل سلوك التحديد العادي ويجعله يتعارض مع توقعات المستخدم.




افترض أن هناك قسمين مثل هذا

.second {
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
  /* Chrome/Safari/Opera */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* IE/Edge */
  -webkit-touch-callout: none;
  /* iOS Safari */
}
<div class="first">
  This is my first div
</div>

<div class="second">
  This is my second div
</div>

تعيين المؤشر على الإعداد الافتراضي بحيث يمنح المستخدم /

يجب استخدام البادئة لدعمها في جميع المتصفحات بدون بادئة ، وقد لا يعمل ذلك في جميع الإجابات.




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

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






Links